深度学习之卷积神经网络CNN(卷积+池化)

张开发
2026/4/8 14:04:24 15 分钟阅读

分享文章

深度学习之卷积神经网络CNN(卷积+池化)
基础的图像操作 图像分类 二值图 1通道每个像素点由01组成 灰度图 1通道每个像素点范围[0,255] 索引图 1通道每个像素点范围[0,255]像素点表示颜色表的索引 RGB真彩图 3通道Red,Green,Blue红绿蓝 importnumpyasnpimportmatplotlib.pyplotaspltimporttorch# 定义函数绘制全黑或全白defdm01():# HWC 高度 宽度 通道img1np.zeros((200,200,3))plt.imshow(img1)plt.show()img2torch.full(size(200,200,3),fill_value255)plt.imshow(img1)plt.axis(off)# 坐标轴隐藏的情况下白色无法显示plt.show()# 定义函数加载图片defdm02():# 加载图片img1plt.imread()print(fimg1:{img1})print(fimg1.shape:{img1.shape})# 保存图片plt.imsave(./data/img_copy.png,img1)plt.imshow(img1)plt.show() 卷积层API用于提取图像的局部特征获取特征图Feature Map 卷积神经网络Convolutional neural netword 卷积层Convolutional用于提取图像的局部特征结合卷积核每个卷积核一个神经元实现处理后的结果叫特征图 池化层Pooling用于降维、降采样 全连接层Full Connected,fc,linear用于预测结果并输出结果 特征图计算方式N (W - F 2 * P)/S 1 W 输入图像的大小 F 卷积核的大小 P 填充的大小 S 步长 N 输出图像的大小特征图大小 importtorchimporttorch.nnasnnimportmatplotlib.pyplotaspltdefdm01():# 1.加载RGB真彩图imgplt.imread(./data/img.jpg)print(fimg:{img},shape:{img.shape})# HWC(640,640,3)# 2.图像形状从HWC-CHW img-张量-转换维度img2torch.tensor(img,dtypetorch.float)img2img2.permute(2,0,1)# CHW(3,640,640)# 3.这里只有1张图片所以增加1个维度从CHW(1,C,H,W)1张3通道的640*640像素的图img3img2.unsqueeze(dim0)## 4.创建卷积层对象提取特征图convnn.Conv2d(3,4,3,2,0)conv_imgconv(img3)# 具体的卷积计算# 5.打印卷积后的结果print(fconv_img:{conv_img},shape:{conv_img.shape})# 6.查看提取到的4个特征图img4conv_img[0]print(fimg4:{img4},shape:{img.shape})# -(4,319,319)# 7.将上述的CHW-HWCimg5img4.permute(1,2,0)print(fimg5:{img5},shape:{img5.shape})# 8.可视化第1个通道的特征图feature1img[:,:,0].detach().numpy()# 第0通道319319像素图plt.imshow(feature1)plt.show() 池化目的是降维 最大池化 平均池化 不会改变数据的通道数 importtorchimporttorch.nnasnn# 单通道池化defdm01():# 1.创建1个通道 3x3的二维矩阵inputstorch.tensor([# 1 通道C[# 3 高度H[1,2,3],# 3 宽度W[3,4,5],[6,7,8]]])print(finputs:{inputs},shape:{inputs.shape})# (1,3,3)# 2.创建最大池化层# 参数一池化核池化窗口大小 参数二补偿 参数三填充pool1nn.MaxPool2d(2,1,0)outputspool1(inputs)# 3.创建平均池化层pool2nn.AvgPool2d(2,1,0)outputspool2(inputs)# 多通道池化defdm02():inputstorch.tensor([# 3 通道C[# 3 高度H[1,2,3],# 3 宽度W[3,4,5],[6,7,8]],[# 通道2HW 3,3[10,20,30],[40,50,60],[70,80,90]],[# 通道3HW 3,3[11,22,33],[44,55,66],[77,88,99]]])CNN图像分类案例 CNN图像分类 1.准备数据使用计算机视觉模块torchvision自带的CIFAR10数据集包含6w张图片5W张训练姐1W张测试集10个分类每个分类6K张图片 2.搭建卷积神经网络 3.模型训练 4.模型测试 卷积层提取图像局部特征-特征图(Feature Map)计算方式N (W-F2P)//S1每个卷积核都是一个神经元 池化层降维最大池化和平均池化降维只在HW上微调整通道上不改变 importtorchimporttorch.nnasnnfromtorchvision.datasetsimportCIFAR10fromtorchvision.transformsimportToTensor# pip install torchvision -i https://mirrors.aliyun.com/pypi/simpleimporttorch.optimasoptimfromtorch.utils.dataimportDataLoaderimporttimeimportmatplotlib.pyplotaspltfromtorchsummaryimportsummary# 每批次样本数Batch_SIZE8# 准备数据集defcreate_dataset():# 参数一数据集路径 参数二是否训练集 参数三数据预处理-张量数据 参数四是否联网下载train_datasetCIFAR10(root./data,traintrue,transformToTensor(),downloadTrue)test_datasetCIFAR10(root./data,trainFalse,transformToTensor(),downloadTrue)returntrain_dataset,test_dataset# 搭建卷积神经网络classImageModel(nn.Module):# 1.初始化父类成员搭建神经网络def__init__(self):super().__init__(self)# 第1个卷积层输入3通道输出6通道卷积核大小3步长1填充0self.conv1nn.Conv2d(3,6,3,1,0)# 第1个池化层窗口大小2*2步长2填充0self.pool1nn.MaxPool2d(2,2,0)# 第2个卷积层和第2个池化层self.conv2nn.Conv2d(6,16,3,1,0)self.pool2nn.MaxPool2d(2,2,0)# 第1个隐藏层全连接层输入576输出120self.linear1nn.Linear(576,120)# 第2个隐藏层self.linear2nn.Linear(120,84)self.outputnn.Linear(84,10)# 前向传播defforward(self,x):# 卷积层激励层激活函数池化层降维xself.pool1(torch.relu(self.conv1(x)))xself.pool2(torch.relu(self.conv2(x)))# 全连接层只能处理二维激活函数# 参数一样本数行数参数二列数特征数-1自动计算xx.reshape(x.size(0),-1)# 第3层:全连接层加权求和激励层激活函数xtorch.relu(self.linear1(x))# 第4层全连接层加权求和激励层激活函数xtorch.relu(self.linear2(x))# 第5层全连接层加权求和输出层returnself.output(x)# 后续用多分类交叉熵损失函数CrossEntropyLoss Softmax()激活函数损失函数# 模型训练deftrain(train_dataset):dataloaderDataLoader(train_dataset,batch_sizeBATCH_SIZE,shuffleTrue)modelImageModel()# 创建损失函数对象criterionnn.CrossEntropyLoss()# 创建优化器对象optimizeroptim.Adam(model.parameters(),lr1e-3)epochs10forepoch_idxinrange(epochs):# 总损失 总样本数量 预测正确样本个数 训练还是时间total_loss,total_samples,total_correct,start0.0,0,0,time.time()# 遍历数据加载器获取到每批次的数据forx,yindataloader:model.train()y_predmodel(x)losscriterion(y_pred,y)# 计算损失# 梯度清零反向传播参数更新optimizer.zero_grad()loss.backword()optimizer.step()# 统计预测正确的样本个数print(y_pred)print(torch.argmax(y_pred,dim-1))# -1表示行 预测分类print(y)# 真实分类print(torch.argmax(y_pred,dim-1)y)# 是否预测正确print((torch.argmax(y_pred,dim-1)y).sum())# 预测正确的样本个数total_correct(torch.argmax(y_pred,dim-1)y).sum()# 统计当前批次的总损失total_lossloss.item()*len(y)# 第一批总损失第2批总损失……# 统计当前批次的总样本个数total_sampleslen(y)# 一轮训练完毕打印概论的训练信息print(fepoch:{epoch_idx1},loss:{total_loss/total_samples:.5f},acc:{totao_correct/total_samples:.2f},time:{time.time()-start.2f})# 保存模型torch.save(model.state_dict(),./model/image_model.pth)# 模型测试defevaluate(test_dataset):# 1.创建测试集数据加载器dataloaderDataLoader(test_dataset,batch_sizeBATCH_SIZE,shuffleFalse)# 2.创建模型对象modelImageModel()# 3.加载模型参数model.load_state_dict(torch.load(./model/image_model.pth))# 4.定义变量统计预测正确的样本个数总样本数total_correct,total_samples0,0# 5.遍历数据加载器获取到每批次的数据forx,yindataloader:model.eval()# 切换模型模式y_predmodel(x)# 因为训练的时候用了CrossEntropyLoss所以搭建神经网络没有加softmax()激活函数这里要用argmax()来模拟# argmax()功能返回最大值对应的索引充当改图偏的预测分类y_predtorch.argmax(y_pred,dim-1)# -1 表示行# 统计预测正确的样本个数total_correct(torch.argmax(y_pred,dim-1)y).sum()# 统计总样本个数total_sampleslen(y)# 打印正确率print(fAcc:{total_correct/total_samples:.2f})if__name____main__:train_dataset,test_datasetcreate_dataset()print(f训练集{train_dataset.data.shape})# (50000,32,32,3)print(f测试集{test_dataset.data.shape})# (10000,32,32,3)print(f数据类别{train_dataset.class_to_idx})# 图像展示plt.figure(figsize(2,2))plt.imshow(train_dataset.data[1111])# 索引为1111的图像plt.title(train_dataset.targets[1111])plt.show()# 搭建神经网络modelImageModel()#查看模型参数参数一模型 参数二输入维度CHW 通道 高 宽 参数三批次大小summary(model,(3,32,32),batch_sizeBATCH_SIZE)# 模型训练train(train_dataset)# 模型评估evaluate(test_dataset)模型参数如下案例增加优化思路增加卷积核的输出通道卷积核的数量增加全连接层的参数量调整学习率调整优化方法optimizer…调整激活函数……根据提供的数据结构建立CNN模型识别图片中的猫/狗计算预测准确率从网站下载猫/狗图片进行预测fromkeras.preprocessing.imageimportImageDataGenerator train_datagenImageDataGnerator(rescale1./255)training_settrain_datagen.flow_from_directory(./dataset/training_set,target_size(50*50),batch_size32,class_modebinary)#建立cnn模型fromkeras.modelsimportSequentialfromkeras.layersimportConv2D,MaxPool2D,Flatten,Dense modelSequential()#增加卷积层model.add(Conv2D(32,(3,3),input_shape(50*50*3),activationrelu))#增加池化层model.add(MaxPool2D(pool_size(2,2)))#卷阶层model.add(Conv2D(32,(3,3),activationrelu))#池化层model.add(MaxPool2D(pool_size(2,2)))model.add(Flatten())model.add(Dense(units128,activationrelu))model.add(Dense(units1,activationsigmoid))model.compile(optimizeradam,lossbinary_crossentropy,metrics[accuracy])model.summary()#查看模型#模型训练model.fit_generator(training_set,epochs25)#训练数据预测accuracy_trainmodel.evaluate_generator(training_set)print(accuracy_train)#测试数据预测test_settrain_datagen.flow_from_directory(./dataset/training_set,target_size(50*50),batch_size32,class_modebinary)accuracy_testmodel.evaluate_generator(test_set)print(accuracy_test)#加载单张图片进行预测fromkeras.preprocessing.imageimportload_img,img_to_arry pic_dogdog.jpgpic_dogload_img(pic_dog,target_size(50,50))pic_dogimg_to_array(pic_dog)pic_dogpic_dog/255pic_dogimg.reshape(1,50,50,3)resultmodel.predict_classes(pic_dog)print(result)使用VGG16的结构提取图像特征再根据特征建立mlp模型实现猫狗图像识别训练、测试数据dataset\data_vgg对数据进行分离计算测试数据预测准确率从网站下载猫狗图片对其进行预测mlp模型是一个隐藏层10个神经元fromkeras.preprocessing.imageimportload_img,img_to_array img_path1.jpgimgload_img(img_path,target_size(224,224))imgimt_to_array(img)type(img)fromkeras.applications.vgg16importVGG15fromkeras.applications.vgg16importpreprocess_inputimportnumpyasnp model_vggVGG16(weightsimagenet,include_topFalse)xnp.expand_dims(img,axis0)xpreprocess_input(x)print(x.shape)#轮廓特征提取featuresmodel_vgg.predict(x)print(features.shape)featurwsfeatures.reshape(1,7*7*512)print(features.shape)%matplotlib inlinefrommatplotlibimportpyplotasplt figplt.figure(figsize(5,5))imgload_img(img_path,target_size(224,224))plt.imshow(img)#数据分离fromsklearn.model_selectionimporttrain_test_test_split X_train,X_test,y_train,y_test train_test_split(X,y,test_size0.3,random_state50)print(X_train.shape,X_test.shape,X.shape)fromkeras.modelsimportSequentialfromkeras.layersimportDense modelSequential()model.add(Dense(units10,activationrelu,input_dim25088))model.add(Dense(units1,activationsigmoid))model.summary()#配置模型并训练模型model.compile(optimizeradam,lossbinary_crossnetropy,metrics[accuracy])model.fit(X_train,y_train,epochs50)fromsklearn.metricsimportaccuracy_score y_train_predictmodel.predict_classes(X_train)accuracy_trainaccuracy_score(y_train,y_train_predict)print(accuracy_train)#测试准确率y_test_predictmodel.predict_classes(X_test)accuracy_testaccuracy_score(y_test,y_test_predict)print(accuracy_test)img_pathdog.jpgimgload_img(img_path,target_size(224,224))imgimg_to_array(img)Xnp.wxpand_dims(img,axis0)Xpreprocess_input(X)featuresmodel_vgg.predict(x)featuresmodel_reshape(1,7*7*512)resultmodel.predict_classes(features)print(result)

更多文章