Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
12
返回列表 发新帖
楼主: gaohaikuo1

python 卷积神经网络

[复制链接]

391

主题

1222

帖子

3902

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3902
 楼主| 发表于 2023-5-24 21:30:51 | 显示全部楼层
  1. #查看mnist中的照片
复制代码
回复

使用道具 举报

391

主题

1222

帖子

3902

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3902
 楼主| 发表于 2023-5-24 21:51:56 | 显示全部楼层
从数据库中取出图片
  1. import torchvision.datasets.mnist as mnist
  2. from PIL import Image
  3. import numpy as np
  4. def img_save(img,picname):
  5.     pil_img = Image.fromarray(np.uint8(img))
  6.     pil_img.save(picname)

  7. data = mnist.read_image_file("./data/MNIST/raw/train-images-idx3-ubyte")
  8. print(data.shape)
  9. for i in range(0,60000,600):
  10.     img = data[i]
  11.     a = np.array(img)
  12.     img_save(a,"./data1/pic"+str(i)+".jpg")
复制代码
回复

使用道具 举报

391

主题

1222

帖子

3902

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3902
 楼主| 发表于 2023-5-25 00:23:46 | 显示全部楼层
将数据加入dataset
  1. import tensorflow as tf
  2. import random
  3. import pathlib
  4. data_path = pathlib.Path('./data/testphotos')
  5. all_image_paths = list(data_path.glob('*/*'))  
  6. all_image_paths = [str(path) for path in all_image_paths]  # 所有图片路径的列表
  7. random.shuffle(all_image_paths)  # 打散
  8. label_names = sorted(item.name for item in data_path.glob('*/') if item.is_dir())
  9. label_to_index = dict((name, index) for index, name in enumerate(label_names))
  10. all_image_labels = [label_to_index[pathlib.Path(path).parent.name] for path in all_image_paths]
  11. ds = tf.data.Dataset.from_tensor_slices((all_image_paths, all_image_labels))
  12. def load_and_preprocess_from_path_label(path, label):
  13.     image = tf.io.read_file(path)  # 读取图片
  14.     image = tf.image.decode_jpeg(image, channels=3)
  15.     image = tf.image.resize(image, [192, 192])  # 原始图片大小为(266, 320, 3),重设为(192, 192)
  16.     image /= 255.0  # 归一化到[0,1]范围
  17.     return image, label
  18. image_label_ds  = ds.map(load_and_preprocess_from_path_label)
复制代码
回复

使用道具 举报

391

主题

1222

帖子

3902

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3902
 楼主| 发表于 2023-5-25 10:56:18 | 显示全部楼层
回复

使用道具 举报

391

主题

1222

帖子

3902

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3902
 楼主| 发表于 2023-5-25 17:06:40 | 显示全部楼层
回复

使用道具 举报

391

主题

1222

帖子

3902

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3902
 楼主| 发表于 2023-5-25 17:09:45 | 显示全部楼层
最终代码
  1. #本代码实现构筑一个dataset和dataloader
  2. from torch.utils.data import Dataset
  3. import cv2
  4. import numpy as np
  5. import torch
  6. import torch.nn as nn
  7. import torch.nn.functional as F
  8. import torch.optim as optim
  9. import tensorflow as tf
  10. import random
  11. import pathlib
  12. from torch.utils.data import DataLoader

  13. BATCH_SIZE=16
  14. DEVICE=torch.device("cuda"if torch.cuda.is_available()else"cpu")
  15. EPOCHS=100

  16. class TensorDataset(Dataset):
  17.     # TensorDataset继承Dataset, 重载了__init__, __getitem__, __len__
  18.     # 实现将一组Tensor数据对封装成Tensor数据集
  19.     # 能够通过index得到数据集的数据,能够通过len,得到数据集大小

  20.     def __init__(self, data_tensor, target_tensor):
  21.         self.data_tensor = data_tensor
  22.         self.target_tensor = target_tensor

  23.     def __getitem__(self, index):
  24.         return self.data_tensor[index], self.target_tensor[index]

  25.     def __len__(self):
  26.         return self.data_tensor.size(0)    # size(0) 返回当前张量维数的第一维

  27. def getImgPathAndName():
  28.     data_path = pathlib.Path('./data/testphotos')
  29.     all_image_paths = list(data_path.glob('*/*'))
  30.     all_image_paths = [str(path) for path in all_image_paths]  # 所有图片路径的列表
  31.     random.shuffle(all_image_paths)  # 打散,这个操作后顺序重新打乱
  32.     all_images = torch.empty((0, 1, 28, 28), dtype=torch.float32)
  33.     for image_path in all_image_paths:
  34.         img = getDataFromImgPath(image_path)
  35.         all_images = torch.cat([all_images, img], dim=0)
  36.         #img = img.permute(0, 3, 1, 2)
  37.         # 将图像channel提到前面即 [batch size, width, height, channel]-> [batch size, channel, width, height]
  38.     label_names = sorted(item.name for item in data_path.glob('*/') if item.is_dir())
  39.     label_to_index = dict((name, index) for index, name in enumerate(label_names))
  40.     all_image_labels = [label_to_index[pathlib.Path(path).parent.name] for path in all_image_paths]
  41.     all_image_labels = torch.tensor(all_image_labels) #从list转为tensor类型
  42.     return all_images, all_image_labels

  43. def getDataFromImgPath(image_path):
  44.     img = cv2.imread(image_path, 0).astype(np.uint8)
  45.     # 第二个参数0表示灰度图
  46.     img = cv2.resize(img, (28, 28))
  47.     img = img / 255.
  48.     img = torch.from_numpy(img)
  49.     img = torch.tensor(img, dtype=torch.float32)
  50.     img = img.unsqueeze(0)  # 在第一维度上增加一个维度,作为channel大小
  51.     img = img.unsqueeze(0)  # 在第一维度上增加一个维度,作为batch size大小
  52.     return img

  53. all_images, all_image_labels = getImgPathAndName()
  54. # 将数据封装成 Dataset (用 TensorDataset 类)
  55. train_dataset = TensorDataset(all_images, all_image_labels)
  56. train_loader=DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)
  57. # 可使用索引调用数据
  58. #print('tensor_data[0]: ', tensor_dataset[0])

  59. # 可返回数据len
  60. #print('len os tensor_dataset: ', len(tensor_dataset))

  61. class Digit(nn.Module):
  62.     def __init__(self):
  63.         super().__init__()
  64.         self.convl = nn.Conv2d(1,10,5)
  65.         self.conv2 = nn.Conv2d(10,20,3)
  66.         self.fcl = nn.Linear(20*10*10,500)
  67.         self.fc2 = nn.Linear(500,10)
  68.     def forward(self,x):
  69.         input_size = x.size(0)#batch_size
  70.         x = self.convl(x)  #输入:batch*1*28*28,输出:batch*10*24*24(28-5+1)
  71.         x = F.relu(x)#保持shape不变 激活层
  72.         x = F.max_pool2d(x,2,2)#池化层  对图片进行压缩   输入:batch*10*24*24
  73.         #输出 batch*10*12*12
  74.         x = self.conv2(x)#输入:batch*10*12*12  输出:batch*20*(12-3+1)-(12-3+1)
  75.         x = F.relu(x)
  76.         #拉伸
  77.         x = x.view(input_size,-1)  #-1  自动计算维度20*10*10=2000
  78.         #进入全连接层
  79.         x = self.fcl(x)#输入:batch*2000  输出batch*500
  80.         x = F.relu(x)
  81.         x = self.fc2(x)#输入batch*500  输出:batch*10
  82.         output=F.log_softmax(x,dim=1)#计算分类,每个数字的概率值
  83.         return output

  84. #定义优化器
  85. model=Digit().to(DEVICE)
  86. optimizer = optim.Adam(model.parameters())
  87. #定义训练方法
  88. def train_model(model,device,train_loader,optimizer,epoch):
  89.     model.train()#切换成训练模式
  90.     for batch_index,(data,target) in enumerate(train_loader):
  91.         data,target=data.to(device),target.to(device)#部署到device上去
  92.          #梯度初始化为0
  93.         optimizer.zero_grad()
  94.         #训练后的结果
  95.         output=model(data)
  96.         #计算损失
  97.         loss=F.cross_entropy(output,target)#交叉熵损失函数
  98.         #找到概率值最大的下标
  99.         pred = output.max(1,keepdim=True)
  100.         #反向传播
  101.         loss.backward()
  102.         #参数优化
  103.         optimizer.step()
  104.         if batch_index%3000==0:
  105.             print("Train Epoch : {} \t Loss:{:.6f}".format(epoch,loss.item()))

  106. #定义测试方法
  107. def test_model(model,device,imgPath):
  108.     #模拟验证
  109.     data = getDataFromImgPath(imgPath)
  110.     #data = torch.tensor(imgPath)
  111.     model.eval()
  112.     with torch.no_grad():#不会计算梯度,也不会进行反向传播
  113.             data=data.to(device)
  114.             #测试数据
  115.             output=model(data)
  116.             #找到概率值最大的索引
  117.             pred=output.max(1,keepdim=True)[1]#值 索引
  118.             print('该图片判断为:' + str(pred[0][0]))
  119.     return pred

  120. #调用方法
  121. for epoch in range(1,EPOCHS+1):
  122.     train_model(model,DEVICE,train_loader,optimizer,epoch)
  123.     print('当前批次'+str(epoch))
  124.   #  test_model(model,DEVICE,test_loader)

  125. #测试图片
  126. test_model(model,DEVICE,'data\\testphotos\\1\\pic1200.jpg')
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|DiscuzX

GMT+8, 2025-4-13 00:39 , Processed in 0.037775 second(s), 16 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表