卷积神经网络的学习(CNN)
文章目录
前言
一、CNN是什么?
二、CNN的结构
1.卷积层
2.池化层
3.激活函数
三.AI Studio小试身手
总结
前言
以卷积神经网络(CNN)为代表的深度学习方法实现对象识别与分类,是把特征提取完全交给机器、整个特征提取的过程无需手工设计、全部由机器自动完成。
一、CNN是什么?
CNN的目的是以一定的模型对事物进行特征提取,而后根据特征对该事物进行分类、识别、预测或决策等。在这个过程里,最重要的步骤在于特征提取,即如何提取到能最大程度区分事物的特征。如果提取的特征无法将不同的事物进行划分,那么该特征提取步骤将毫无意义。而实现这个伟大的模型的,是对CNN进行迭代训练。
二、CNN的结构
CNN网络一共有5个层级结构:
- 输入层
- 卷积层
- 激活层
- 池化层
- 全连接FC层
1.卷积层
一幅1000*1000的图像,那么它的输入数据将达到10的六次方,可以利用空间结构关系有效地降低输出尺度,进而减少模型所需要学习的参数量,提高算法的训练效率。而且,第一个卷积层会直接接受图像像素级的输入,每一个卷积操作只会处理一小块图像,每经过一次卷积核所得到的新的图像像素都是对原图像最有效的特征提取。
2.池化层
池化层的作用是保留最显著的特征,一般常用最大池化法和平均池化法。
卷积层和池化层中过滤器移动的方式是相似的,唯一的区别就是卷积层使用的过滤器是横跨整个输入节点矩阵的深度,而池化层使用的过滤器只影响一个深度上的节点。所以池化层的过滤器除了在长和宽两个维度移动,还需要在深度这个维度上移动。
3.激活函数
激活函数是向神经网络中引入非线性因素,通过激活函数神经网络就可以拟合各种曲线。激活函数主要分为饱和激活函数(Saturated Neurons)和非饱和函数(One-sided Saturations)。
非饱和激活函数的优势(如ReLU):
1.非饱和激活函数可以解决梯度消失问题。
2.非饱和激活函数可以加速收敛。
三.AI Studio小试身手
CNN实现猫狗分类 - 飞桨AI Studio (baidu.com)
定义一个较简单的卷积神经网络。其结构为:输入的二维图像,先经过三次卷积层、池化层和Batchnorm,再经过全连接层,最后使用softmax分类作为输出层。
关键代码学习
1.三个池化层的定义
def convolutional_neural_network(img):# 第一个卷积-池化层conv_pool_1 = fluid.nets.simple_img_conv_pool(input=img, # 输入图像filter_size=5, # 滤波器的大小num_filters=20, # filter 的数量。它与输出的通道相同pool_size=2, # 池化核大小2*2pool_stride=2, # 池化步长act="relu") # 激活类型conv_pool_1 = fluid.layers.batch_norm(conv_pool_1)# 第二个卷积-池化层conv_pool_2 = fluid.nets.simple_img_conv_pool(input=conv_pool_1,filter_size=5,num_filters=50,pool_size=2,pool_stride=2,act="relu")conv_pool_2 = fluid.layers.batch_norm(conv_pool_2)# 第三个卷积-池化层conv_pool_3 = fluid.nets.simple_img_conv_pool(input=conv_pool_2,filter_size=5,num_filters=50,pool_size=2,pool_stride=2,act="relu")# 以softmax为激活函数的全连接输出层,10类数据输出10个数字prediction = fluid.layers.fc(input=conv_pool_3, size=10, act='softmax')return prediction
2.定义绘制训练过程的损失值和准确率变化趋势的方法draw_train_process
all_train_iter=0
all_train_iters=[]
all_train_costs=[]
all_train_accs=[]def draw_train_process(title,iters,costs,accs,label_cost,lable_acc):plt.title(title, fontsize=24)plt.xlabel("iter", fontsize=20)plt.ylabel("cost/acc", fontsize=20)plt.plot(iters, costs,color='red',label=label_cost) plt.plot(iters, accs,color='green',label=lable_acc) plt.legend()plt.grid()plt.show()
3.训练并保存模型
EPOCH_NUM = 20
model_save_dir = "/home/aistudio/work/catDogModel"
# 获取测试程序
test_program = fluid.default_main_program().clone(for_test=True)
for pass_id in range(EPOCH_NUM):# 开始训练for batch_id, data in enumerate(train_reader()): #遍历train_reader的迭代器,并为数据加上索引batch_idtrain_cost,train_acc = exe.run(program=fluid.default_main_program(),#运行主程序feed=feeder.feed(data), #喂入一个batch的数据fetch_list=[avg_cost, acc]) #fetch均方误差和准确率all_train_iter=all_train_iter+BATCH_SIZEall_train_iters.append(all_train_iter)all_train_costs.append(train_cost[0])all_train_accs.append(train_acc[0])#每100次batch打印一次训练、进行一次测试if batch_id % 100 == 0: print('Pass:%d, Batch:%d, Cost:%0.5f, Accuracy:%0.5f' % (pass_id, batch_id, train_cost[0], train_acc[0]))# 开始测试test_costs = [] #测试的损失值test_accs = [] #测试的准确率for batch_id, data in enumerate(test_reader()):test_cost, test_acc = exe.run(program=test_program, #执行测试程序feed=feeder.feed(data), #喂入数据fetch_list=[avg_cost, acc]) #fetch 误差、准确率test_costs.append(test_cost[0]) #记录每个batch的误差test_accs.append(test_acc[0]) #记录每个batch的准确率# 求测试结果的平均值test_cost = (sum(test_costs) / len(test_costs)) #计算误差平均值(误差和/误差的个数)test_acc = (sum(test_accs) / len(test_accs)) #计算准确率平均值( 准确率的和/准确率的个数)print('Test:%d, Cost:%0.5f, ACC:%0.5f' % (pass_id, test_cost, test_acc))#保存模型
# 如果保存路径不存在就创建
if not os.path.exists(model_save_dir):os.makedirs(model_save_dir)
print ('save models to %s' % (model_save_dir))
fluid.io.save_inference_model(model_save_dir,['images'],[predict],exe)
print('训练模型保存完成!')
draw_train_process("training",all_train_iters,all_train_costs,all_train_accs,"trainning cost","trainning acc")
总结
对于CNN的实际应用有了大体的认识,但是不够深刻,只停留在生搬硬套上了。对于卷积层、池化层只明白了相关概念,但是不知道如何去应用。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
