当前位置:   article > 正文

(3)paddle---近视眼睛分类的例子_pred_area = paddle.concat(pred_area)

pred_area = paddle.concat(pred_area)

1主要参考

(1)paddle的API官方地址

Conv2D-API文档-PaddlePaddle深度学习平台

(2)本教程和以下教程不够详细,还是推荐下面这个大佬的blog看一下

计算机视觉——眼疾图片识别(数据集iChallenge-PM)_「已注销」的博客-CSDN博客

(3)blibli视频

252-06_预测病理性近视_图片数据读取_dec_哔哩哔哩_bilibili

 (4)数据集地址

眼疾识别数据集iChallenge-PM - 飞桨AI Studio

2、数据集介绍

(1)数据集

iChallenge-PM是百度大脑和中山大学中山眼科中心联合举办的iChallenge比赛中,提供的关于病理性近视(Pathologic Myopia,PM)的医疗类数据集,包含1200个受试者的眼底视网膜图片,训练、验证和测试数据集各400张。 training.zip:包含训练中的图片和标签
validation.zip:包含验证集的图片
valid_gt.zip:包含验证集的标签  

iChallenge-PM中既有病理性近视患者的眼底图片,也有非病理性近视患者的图片,命名规则如下: 病理性近视(PM):文件名以P开头
非病理性近视(non-PM): 高度近似(high myopia):文件名以H开头
正常眼睛(normal):文件名以N开头

(2)所使用的文件

1)解压3个压缩包,拷贝出来需要的

 2)将valid_gt.zip中的压缩包中的excel另存为.csv文件,另存后,注意删除最后的两行空数据

3)剩下来,建议看大佬的代码吧

计算机视觉——眼疾图片识别(数据集iChallenge-PM)_「已注销」的博客-CSDN博客

3、基于Lenet的程序实现(基础实现) 

(1)程序测试代码

  1. import cv2
  2. import random
  3. import numpy as np
  4. import os
  5. import paddle
  6. import paddle.nn.functional as F
  7. from paddle.nn import Conv2D, MaxPool2D, Linear, Dropout
  8. #对读入的图像数据进行预处理
  9. def transform_img(img):
  10. #将图片尺寸缩放到 224 * 224
  11. img = cv2.resize(img, (224,224))
  12. #读取的图像数据格式是[H, W, C]
  13. #使用转置操作将其变成[C, H, W]
  14. img = np.transpose(img,(2,0,1))
  15. #归一化操作,将数据范围调整到[-1.0, 1.0]之间
  16. img = img / 255
  17. img = img * 2.0 -1.0
  18. return img
  19. #定义训练集数据读取器
  20. def data_loader(datadir, batch_size=10, mode='train'):
  21. #将datadir目录下的文件列出来,每条文件都读入
  22. filenames = os.listdir(datadir)
  23. def reader():
  24. # print("chen_filenames")
  25. # print(filenames)
  26. #只有在训练的时随机打乱数据顺序,测试的时候不打乱
  27. if mode == 'train':
  28. random.shuffle(filenames)
  29. batch_imgs = []
  30. batch_labels = []
  31. for name in filenames:
  32. filepath = os.path.join(datadir,name)
  33. img = cv2.imread(filepath)
  34. img = transform_img(img)
  35. if name[0] == 'H' or name[0] == 'N':
  36. # H开头的文件名表示高度近似,N开头的文件名表示正常视力
  37. # 高度近似和正常视力的样板,都不是病理性的,属于负样本,标签为0
  38. label = 0
  39. elif name[0] == 'P':
  40. # P开头的是病理性近似,属于正样本,标签为1
  41. label = 1
  42. else:
  43. raise('Not excepted file name')
  44. #每读取一个样板的数据,就将其放入数据列表中
  45. batch_imgs.append(img)
  46. batch_labels.append(label)
  47. if len(batch_imgs) == batch_size:
  48. # 当数据列表的长度等于batch_size的时候
  49. # 把这些数据当做一个mini-batch,并作为数据生成器的一个输出
  50. imgs_array = np.array(batch_imgs).astype('float32')
  51. labels_array = np.array(batch_labels).astype('float32').reshape(-1,1)
  52. # yield的作用:返回一个可以用来迭代(for循环)的生成器,
  53. # 它的应用场景通常为一个需要返回一系列值的,含有循环的函数中
  54. yield imgs_array, labels_array
  55. batch_imgs = []
  56. batch_labels = []
  57. #上面都循环结束了,如何还有剩下的,也就是样板数/batch_size数没有整除
  58. if len(batch_imgs) > 0:
  59. imgs_array = np.array(batch_imgs).astype('float32')
  60. labels_array = np.array(batch_labels).astype('float32').reshape(-1,1)
  61. # yield的作用:返回一个可以用来迭代(for循环)的生成器,
  62. # 它的应用场景通常为一个需要返回一系列值的,含有循环的函数中
  63. yield imgs_array, labels_array
  64. return reader
  65. EPOCH_NUM = 5
  66. #定义训练过程
  67. def train_pm(model, optimizer):
  68. # 开启0号GPU训练
  69. use_gpu = True
  70. paddle.device.set_device('gpu:0') if use_gpu else paddle.device.set_device('cpu')
  71. print('start training ...')
  72. model.train()
  73. # 定义数据读取器,训练数据读取器和验证数据读取器
  74. train_loader = data_loader(DATADIR, batch_size=10, mode='train')
  75. for epoch in range(EPOCH_NUM):
  76. for batch_id, data in enumerate(train_loader()): #在返回的reader里面调用函数,调用的就是yield中的枚举返回值
  77. x_data, y_data = data
  78. img = paddle.to_tensor(x_data)
  79. label = paddle.to_tensor(y_data)
  80. # 运行模型进行前向推理计算,得到预测值
  81. logits = model(img)
  82. loss = F.binary_cross_entropy_with_logits(logits, label)
  83. avg_loss = paddle.mean(loss)
  84. if batch_id % 20 == 0:
  85. print("epoch: {},batch_id: {}, loss is: {:.4f}".format(epoch, batch_id, float(avg_loss.numpy())))
  86. #反向传播,更新权重,清除梯度
  87. avg_loss.backward()
  88. optimizer.step()
  89. #每一个epoch结束都测试一下
  90. model.eval()
  91. accuracies = []
  92. losses = []
  93. valid_loader = data_loader(DATADIR, batch_size=10, mode='eval')
  94. for batch_id, data in enumerate(valid_loader()):
  95. x_data, y_data = data
  96. img = paddle.to_tensor(x_data)
  97. label = paddle.to_tensor(y_data)
  98. #运行模型前向计算,得到预测值
  99. logits = model(img)
  100. # 二分类,sigmoid计算后的结果以0.5为阈值分两个类型
  101. # 计算sigmoid后的预测概率,进行loss计算
  102. pred = F.sigmoid(logits) # P正的概率
  103. loss = F.binary_cross_entropy_with_logits(logits,label)
  104. #计算概率小于0.5的类别
  105. pred2 = pred*(-1.0) + 1.0 # P负的概率,也就是1-P正
  106. #得到两个类别的预测概率,并沿第一个维度级联
  107. pred = paddle.concat([pred2, pred],axis=1)
  108. #原因是paddle.metric.accuracy的输入要是每个类别的概率,所以拼接了一下
  109. acc = paddle.metric.accuracy(pred, paddle.cast(label,dtype='int64'))
  110. accuracies.append(acc.numpy())
  111. losses.append(loss.numpy())
  112. print("[validation] accuracy /loss: {:.4f}/{:.4f}".format(np.mean(accuracies),np.mean(losses))) #求平均
  113. model.train()
  114. paddle.save(model.state_dict(),'palm.pdparams')
  115. paddle.save(optimizer.state_dict(),'palm.pdopt')
  116. #定义评国过程
  117. def evaluation(model, params_file_path):
  118. # 开启0号GPU预估
  119. use_gpu = True
  120. paddle.device.set_device('gpu:0') if use_gpu else paddle.device.set_device('cpu')
  121. print('start evaluation ...')
  122. #加载模型参数
  123. model_state_dict = paddle.load(params_file_path)
  124. model.load_dict(model_state_dict)
  125. model.eval()
  126. eval_loader = data_loader(DATADIR, batch_size=10, mode='eval')
  127. acc_set = []
  128. avg_loss_set = []
  129. for batch_id, data in enumerate(eval_loader()):
  130. x_data, y_data =data
  131. img = paddle.to_tensor(x_data)
  132. label = paddle.to_tensor(y_data)
  133. y_data = y_data.astype(np.int64)
  134. label_64 = paddle.to_tensor(y_data)
  135. #计算预测和精度
  136. #模型的forward方法这两个封装了对img, label_64的判断,如果传入了label,则也返回acc
  137. prediction, acc = model(img, label_64)
  138. # 计算损失函数值
  139. loss = F.binary_cross_entropy_with_logits(prediction, label)
  140. avg_loss = paddle.mean(loss)
  141. acc_set.append(float(acc.numpy()))
  142. avg_loss_set.append(float(avg_loss.numpy()))
  143. #求平均精度
  144. acc_val_mean = np.array(acc_set).mean()
  145. avg_loss_val_mean = np.array(avg_loss_set).mean()
  146. print('loss={:.4f}, acc={:.4f}'.format(avg_loss_val_mean,acc_val_mean))
  147. #定义Lenet网络结果
  148. # class Lenet(paddle.nn.Layer):
  149. # pass
  150. # 定义 LeNet 网络结构
  151. class LeNet(paddle.nn.Layer):
  152. def __init__(self, num_classes=1):
  153. super(LeNet, self).__init__()
  154. # 创建卷积和池化层块,每个卷积层使用Sigmoid激活函数,后面跟着一个2x2的池化
  155. self.conv1 = Conv2D(in_channels=3, out_channels=6, kernel_size=5)
  156. self.max_pool1 = MaxPool2D(kernel_size=2, stride=2)
  157. self.conv2 = Conv2D(in_channels=6, out_channels=16, kernel_size=5)
  158. self.max_pool2 = MaxPool2D(kernel_size=2, stride=2)
  159. # 创建第3个卷积层
  160. self.conv3 = Conv2D(in_channels=16, out_channels=120, kernel_size=4)
  161. # 创建全连接层,第一个全连接层的输出神经元个数为64, 第二个全连接层输出神经元个数为分类标签的类别数
  162. self.fc1 = Linear(in_features=300000, out_features=64)
  163. self.fc2 = Linear(in_features=64, out_features=num_classes)
  164. # 网络的前向计算过程
  165. def forward(self, x, label=None):
  166. x = self.conv1(x)
  167. x = F.sigmoid(x)
  168. x = self.max_pool1(x)
  169. x = self.conv2(x)
  170. x = F.sigmoid(x)
  171. x = self.max_pool2(x)
  172. x = self.conv3(x)
  173. x = F.sigmoid(x)
  174. x = paddle.reshape(x, [x.shape[0], -1])
  175. x = self.fc1(x)
  176. x = self.fc2(x)
  177. if label is not None:
  178. acc = paddle.metric.accuracy(input=x,label=label)
  179. return x,acc
  180. else:
  181. return x
  182. # 数据的路径
  183. DATADIR = '/home/chen/deep_data/eye_ill/training/PALM-Training400'
  184. #创建模型
  185. model = LeNet(num_classes=1)
  186. #启动训练过程
  187. opt = paddle.optimizer.Momentum(learning_rate=0.001,momentum=0.9,
  188. parameters=model.parameters())
  189. train_pm(model,optimizer=opt)
  190. evaluation(model,params_file_path='palm.pdparams')

(2)5个epoch的测试结果

4、基于paddle.nn的程序实现(修改了大佬代码,丢弃paddle.fluid) 

(1)看了一下paddle的api, paddle.fluid已经被丢弃

 (2)主要修改注意事项

4.1 Conv2D函数

Conv2D-API文档-PaddlePaddle深度学习平台

class paddle.nn.Conv2D(in_channelsout_channelskernel_sizestride=1padding=0dilation=1groups=1padding_mode='zeros'weight_attr=Nonebias_attr=Nonedata_format='NCHW')

  • in_channels (int) - 输入图像的通道数。

  • out_channels (int) - 由卷积操作产生的输出的通道数。

  • kernel_size (int|list|tuple) - 卷积核大小。可以为单个整数或包含两个整数的元组或列表,分别表示卷积核的高和宽。如果为单个整数,表示卷积核的高和宽都等于该整数。

  • stride (int|list|tuple,可选) - 步长大小。可以为单个整数或包含两个整数的元组或列表,分别表示卷积沿着高和宽的步长。如果为单个整数,表示沿着高和宽的步长都等于该整数。默认值:1。

  • padding (int|list|tuple|str,可选) - 填充大小。如果它是一个字符串,可以是"VALID"或者"SAME",表示填充算法,计算细节可参考上述 padding = "SAME"或 padding = "VALID" 时的计算公式。如果它是一个元组或列表,它可以有3种格式:(1)包含4个二元组:当 data_format 为"NCHW"时为 [[0,0], [0,0], [padding_height_top, padding_height_bottom], [padding_width_left, padding_width_right]],当 data_format 为"NHWC"时为[[0,0], [padding_height_top, padding_height_bottom], [padding_width_left, padding_width_right], [0,0]];(2)包含4个整数值:[padding_height_top, padding_height_bottom, padding_width_left, padding_width_right];(3)包含2个整数值:[padding_height, padding_width],此时padding_height_top = padding_height_bottom = padding_height, padding_width_left = padding_width_right = padding_width。若为一个整数,padding_height = padding_width = padding。默认值:0。

(2)fluid和nn的主要的修改对比如下

  1. self.conv1 = paddle.fluid.dygraph.nn.Conv2D(num_channels=3, num_filters=6, filter_size=5,act='sigmoid')
  2. self.conv1= paddle.nn.Conv2D(in_channels=3,out_channels=6,kernel_size=5) #sigmoid单独在forward中实现

4.2MaxPool2D

(1)函数说明

MaxPool2D-API文档-PaddlePaddle深度学习平台

paddle.nn.MaxPool2D(kernel_sizestride=Nonepadding=0ceil_mode=Falsereturn_mask=Falsedata_format='NCHW'name=None)

  • ernel_size (int|list|tuple): 池化核大小。如果它是一个元组或列表,它必须包含两个整数值, (pool_size_Height, pool_size_Width)。若为一个整数,则它的平方值将作为池化核大小,比如若pool_size=2, 则池化核大小为2x2。

  • stride (int|list|tuple,可选):池化层的步长。如果它是一个元组或列表,它将包含两个整数,(pool_stride_Height, pool_stride_Width)。若为一个整数,则表示H和W维度上stride均为该值。默认值为None, 这时会使用kernel_size作为stride。

  • padding (str|int|list|tuple,可选) 池化填充。如果它是一个字符串,可以是"VALID"或者"SAME",表示填充算法。如果它是一个元组或列表,它可以有3种格式:(1)包含2个整数值:[pad_height, pad_width];(2)包含4个整数值:[pad_height_top, pad_height_bottom, pad_width_left, pad_width_right];(3)包含4个二元组:当 data_format 为"NCHW"时为 [[0,0], [0,0], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right]],当 data_format 为"NHWC"时为[[0,0], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right], [0,0]]。若为一个整数,则表示H和W维度上均为该值。默认值:0。

  • ceil_mode (bool,可选):是否用ceil函数计算输出高度和宽度。如果是True,则使用 ceil 计算输出形状的大小。

  • return_mask (bool,可选):是否返回最大索引和输出。默认为False.

  • data_format (str,可选): 输入和输出的数据格式,可以是"NCHW"和"NHWC"。N是批尺寸,C是通道数,H是特征高度,W是特征宽度。默认值:"NCHW"

  • name (str,可选):函数的名字,默认为None.

 (2)fluid和nn的主要的修改对比如下

  1. self.pool1 = paddle.fluid.dygraph.nn.Pool2D(pool_size=2, pool_stride=2, pool_type='max')
  2. self.pool1 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)

4.3 Linear

Linear-API文档-PaddlePaddle深度学习平台

(1)函数定义

class paddle.nn.Linear(in_featuresout_featuresweight_attr=Nonebias_attr=Nonename=None)

  • in_features (int) – 线性变换层输入单元的数目。

  • out_features (int) – 线性变换层输出单元的数目。

  • weight_attr (ParamAttr, 可选) – 指定权重参数的属性。默认值为None,表示使用默认的权重参数属性,将权重参数初始化为0。具体用法请参见 ParamAttr 。

  • bias_attr (ParamAttr|bool, 可选) – 指定偏置参数的属性。 bias_attrbias_attr 为bool类型且设置为False时,表示不会为该层添加偏置。 bias_attrbias_attr 如果设置为True或者None,则表示使用默认的偏置参数属性,将偏置参数初始化为0。具体用法请参见 ParamAttr 。默认值为None。

  • name (str,可选) – 具体用法请参见 Name ,一般无需设置,默认值为None。

(2)fluid和nn的主要的修改对比如下

  1. self.fc1 = paddle.fluid.dygraph.nn.Linear(input_dim=300000, output_dim=64, act='sigmoid')
  2. self.fc1 = paddle.nn.Linear(in_features=300000, out_features=64)#sigmoid单独在forward中实现

4.4sigmoid_cross_entropy_with_logits

binary_cross_entropy_with_logits-API文档-PaddlePaddle深度学习平台

(1)fluid.layers.sigmoid_cross_entropy_with_logits的定义

 (2)paddle.nn.functional.binary_cross_entropy_with_logits的定义

4.5 基于新版API的paddle.nn的实现

(1)测试代码

  1. import cv2
  2. import os
  3. import random
  4. import numpy as np
  5. #已丢弃
  6. # import paddle.fluid as fluid
  7. # from paddle.fluid.dygraph.nn import Conv2D, Pool2D, Linear
  8. import paddle
  9. import paddle.nn.functional as F
  10. from paddle.nn import Conv2D, MaxPool2D, Linear, Dropout
  11. """
  12. 数据集iChallenge-PM(眼疾识别)
  13. """
  14. def transform_img(img):
  15. img = cv2.resize(img, (224, 224))
  16. img = np.transpose(img, (2, 0, 1))
  17. img = img.astype('float32')
  18. img = img / 255.
  19. img = img * 2.0 - 1.0
  20. return img
  21. def data_loader(datadir, batch_size=10, mode='train'):
  22. filenames = os.listdir(datadir)
  23. def reader():
  24. if mode == 'train':
  25. random.shuffle(filenames)
  26. batch_imgs = []
  27. batch_labels = []
  28. for name in filenames:
  29. filepath = os.path.join(datadir, name)
  30. img = cv2.imread(filepath)
  31. img = transform_img(img)
  32. if name[0] == 'H':
  33. label = 0
  34. elif name[0] == 'N':
  35. label = 0
  36. elif name[0] == 'P':
  37. label = 1
  38. else:
  39. print('Not excepted file name')
  40. print(name[0])
  41. exit(-1)
  42. batch_imgs.append(img)
  43. batch_labels.append(label)
  44. if len(batch_imgs) == batch_size:
  45. imgs_array = np.array(batch_imgs).astype('float32')
  46. labels_array = np.array(batch_labels).astype(
  47. 'float32').reshape(-1, 1)
  48. yield imgs_array, labels_array
  49. batch_imgs = []
  50. batch_labels = []
  51. if len(batch_imgs) > 0:
  52. imgs_array = np.array(batch_imgs).astype('float32')
  53. labels_array = np.array(batch_labels).astype('float32').reshape(
  54. -1, 1)
  55. yield imgs_array, labels_array
  56. return reader
  57. def valid_data_loader(datadir, csvfile, batch_size=10, mode='valid'):
  58. filelists = open(csvfile).readlines()
  59. def reader():
  60. batch_imgs = []
  61. batch_labels = []
  62. for line in filelists[1:]:
  63. line = line.strip().split(',')
  64. name = line[1]
  65. label = int(line[2])
  66. filepath = os.path.join(datadir, name)
  67. img = cv2.imread(filepath)
  68. img = transform_img(img)
  69. batch_imgs.append(img)
  70. batch_labels.append(label)
  71. if len(batch_imgs) == batch_size:
  72. imgs_array = np.array(batch_imgs).astype('float32')
  73. labels_array = np.array(batch_labels).astype(
  74. 'float32').reshape(-1, 1)
  75. yield imgs_array, labels_array
  76. batch_imgs = []
  77. batch_labels = []
  78. if len(batch_imgs) > 0:
  79. imgs_array = np.array(batch_imgs).astype('float32')
  80. labels_array = np.array(batch_labels).astype('float32').reshape(
  81. -1, 1)
  82. yield imgs_array, labels_array
  83. return reader
  84. DATADIR = 'D:/pytorch_learning2022/data/eye/PALM-Training400'
  85. DATADIR2 = 'D:/pytorch_learning2022/data/eye/PALM-Validation400'
  86. CSCVFILE = 'D:/pytorch_learning2022/data/eye/PM_Label_and_Fovea_Location.csv'
  87. # 定义LeNet的网络结构
  88. class LeNet(paddle.nn.Layer):
  89. def __init__(self, name_scope, num_classes=1):
  90. super(LeNet, self).__init__(name_scope)
  91. # self.conv1 = paddle.fluid.dygraph.nn.Conv2D(num_channels=3, num_filters=6, filter_size=5,act='sigmoid')
  92. # self.conv1= paddle.nn.Conv2D(in_channels=3,out_channels=6,kernel_size=5) #sigmoid单独在forward中实现
  93. self.conv1= Conv2D(in_channels=3,out_channels=6,kernel_size=5) #sigmoid单独在forward中实现
  94. # self.pool1 = paddle.fluid.dygraph.nn.Pool2D(pool_size=2, pool_stride=2, pool_type='max')
  95. # self.pool1 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
  96. self.pool1 = MaxPool2D(kernel_size=2, stride=2)
  97. # self.conv2 = Conv2D(num_channels=6,num_filters=16,filter_size=5,act='sigmoid')
  98. self.conv2= Conv2D(in_channels=6,out_channels=16,kernel_size=5) #sigmoid单独在forward中实现
  99. # self.pool2 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
  100. self.pool2 = MaxPool2D(kernel_size=2, stride=2)
  101. # self.conv3 = Conv2D(num_channels=16,num_filters=120, filter_size=4, act='sigmoid')
  102. self.conv3= Conv2D(in_channels=16,out_channels=120,kernel_size=4) #sigmoid单独在forward中实现
  103. # self.fc1 = paddle.fluid.dygraph.nn.Linear(input_dim=300000, output_dim=64, act='sigmoid')
  104. # self.fc1 = paddle.nn.Linear(in_features=300000, out_features=64)#sigmoid单独在forward中实现
  105. self.fc1 = Linear(in_features=300000, out_features=64) #sigmoid单独在forward中实现
  106. # self.fc2 = Linear(input_dim=64, output_dim=num_classes)
  107. self.fc2 = Linear(in_features=64, out_features=num_classes)
  108. def forward(self, x):
  109. x = self.conv1(x)
  110. x = F.sigmoid(x)
  111. x = self.pool1(x)
  112. x = self.conv2(x)
  113. x = F.sigmoid(x)
  114. x = self.pool2(x)
  115. x = self.conv3(x)
  116. x = F.sigmoid(x)
  117. # x = fluid.layers.reshape(x, [x.shape[0], -1])
  118. x = paddle.reshape(x, [x.shape[0], -1])
  119. x = self.fc1(x)
  120. x = F.sigmoid(x)
  121. x = self.fc2(x)
  122. return x
  123. # 定义AlexNet网络结构
  124. class AlexNet(paddle.nn.Layer):
  125. def __init__(self, name_scope, num_classes=1):
  126. super(AlexNet, self).__init__(name_scope)
  127. name_scope = self.full_name
  128. # self.conv1 = Conv2D(num_channels=3, num_filters=96,filter_size=11, stride=4, padding=5,act='relu')
  129. self.conv1= Conv2D(in_channels=3,out_channels=96,kernel_size=5,stride=4,padding=5) #relu单独在forward中实现
  130. # self.pool1 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
  131. self.pool1 = MaxPool2D(kernel_size=2, stride=2)
  132. # self.conv2 = Conv2D(num_channels=96,num_filters=256,filter_size=5,stride=1,padding=2, act='relu')
  133. self.conv2= Conv2D(in_channels=96,out_channels=256,kernel_size=5,stride=1,padding=2) #relu单独在forward中实现
  134. # self.pool2 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
  135. self.pool2 = MaxPool2D(kernel_size=2, stride=2)
  136. # self.conv3 = Conv2D(num_channels=256,num_filters=384,filter_size=3,stride=1,padding=1,act='relu')
  137. self.conv3 = Conv2D(in_channels=256,out_channels=384,kernel_size=3,stride=1,padding=1) #relu单独在forward中实现
  138. # self.conv4 = Conv2D(num_channels=384,num_filters=384,filter_size=3,stride=1,padding=1,act='relu')
  139. self.conv4 = Conv2D(in_channels=384,out_channels=384,kernel_size=3,stride=1,padding=1) #relu单独在forward中实现
  140. # self.conv5 = Conv2D(num_channels=384,num_filters=256,filter_size=3,stride=1,padding=1,act='relu')
  141. self.conv5 = Conv2D(in_channels=384,out_channels=256,kernel_size=3,stride=1,padding=1) #relu单独在forward中实现
  142. # self.pool5 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
  143. self.pool5 = MaxPool2D(kernel_size=2, stride=2)
  144. # self.fc1 = Linear(input_dim=12544, output_dim=4096, act='relu')
  145. self.fc1 = Linear(in_features=12544, out_features=4096) #relu单独在forward中实现
  146. self.drop_ratio1 = 0.5
  147. # self.fc2 = Linear(input_dim=4096, output_dim=4096, act='relu')
  148. self.fc2 = Linear(in_features=4096, out_features=4096) #relu单独在forward中实现
  149. self.drop_ratio2 = 0.5
  150. # self.fc3 = Linear(input_dim=4096, output_dim=num_classes)
  151. self.fc3 = Linear(in_features=4096, out_features=num_classes)
  152. def forward(self, x):
  153. x = self.conv1(x)
  154. x = F.relu(x)
  155. x = self.pool1(x)
  156. x = self.conv2(x)
  157. x = F.relu(x)
  158. x = self.pool2(x)
  159. x = self.conv3(x)
  160. x = F.relu(x)
  161. x = self.conv4(x)
  162. x = F.relu(x)
  163. x = self.conv5(x)
  164. x = F.relu(x)
  165. x = self.pool5(x)
  166. # x = fluid.layers.reshape(x, [x.shape[0], -1])
  167. x = paddle.reshape(x, [x.shape[0], -1])
  168. x = self.fc1(x)
  169. x = F.relu(x)
  170. x = F.dropout(x, self.drop_ratio1)
  171. x = self.fc2(x)
  172. x = F.relu(x)
  173. x = F.dropout(x, self.drop_ratio2)
  174. x = self.fc3(x)
  175. return x
  176. # 定义训练过程
  177. def train(model):
  178. print("---- start training ----")
  179. model.train()
  180. epoch_num = 5
  181. # opt = fluid.optimizer.Momentum(learning_rate=0.001,momentum=0.9, parameter_list=model.parameters())
  182. opt = paddle.optimizer.Momentum(learning_rate=0.001, momentum=0.9, parameters=model.parameters())
  183. train_loader = data_loader(DATADIR, batch_size=10, mode='train')
  184. valid_loader = valid_data_loader(DATADIR2, CSCVFILE)
  185. for epoch in range(epoch_num):
  186. for batch_id, data in enumerate(train_loader()):
  187. x_data, y_data = data
  188. img = paddle.to_tensor(x_data)
  189. label = paddle.to_tensor(y_data)
  190. logits = model(img)
  191. # loss = fluid.layers.sigmoid_cross_entropy_with_logits(logits, label)
  192. loss = F.binary_cross_entropy_with_logits(logits, label) #是否有问题待确认
  193. avg_loss = paddle.mean(loss)
  194. if batch_id % 10 == 0:
  195. print("epoch: {}, batch_id: {}, loss is: {}".format(
  196. epoch, batch_id, avg_loss.numpy()))
  197. avg_loss.backward()
  198. opt.minimize(avg_loss)
  199. model.clear_gradients()
  200. model.eval()
  201. accuracies = []
  202. losses = []
  203. for batch_id, data in enumerate(valid_loader()):
  204. x_data, y_data = data
  205. img = paddle.to_tensor(x_data)
  206. label = paddle.to_tensor(y_data)
  207. logits = model(img)
  208. pred = F.sigmoid(logits)
  209. # loss = fluid.layers.sigmoid_cross_entropy_with_logits(logits, label)
  210. loss = F.binary_cross_entropy_with_logits(logits, label)
  211. pred2 = pred * (-1.0) + 1.0
  212. # pred = fluid.layers.concat([pred2, pred], axis=1)
  213. pred = paddle.concat([pred2, pred], axis=1)
  214. # acc = fluid.layers.accuracy(pred, fluid.layers.cast(label, dtype='int64'))
  215. acc = paddle.metric.accuracy(pred, paddle.cast(label,dtype='int64'))
  216. accuracies.append(acc.numpy())
  217. losses.append(loss.numpy())
  218. print("[validation accuracy/loss: {}/{}]".format(
  219. np.mean(accuracies), np.mean(losses)))
  220. model.train()
  221. # fluid.save_dygraph(model.state_dict(), 'D:/pytorch_learning2022/00_01paddle_learning/result/iChallengePM')
  222. # fluid.save_dygraph(opt.state_dict(), 'D:/pytorch_learning2022/00_01paddle_learning/result/iChallengePM')
  223. paddle.save(model.state_dict(),'palm.pdparams')
  224. paddle.save(opt.state_dict(),'palm.pdopt')
  225. if __name__ == "__main__":
  226. # use_gpu = True
  227. use_gpu = False
  228. paddle.device.set_device('gpu:0') if use_gpu else paddle.device.set_device('cpu')
  229. # with fluid.dygraph.guard():
  230. # model = LeNet("LeNet")
  231. # model = AlexNet("AlexNet")
  232. # model = LeNet("LeNet")
  233. model = AlexNet("AlexNet")
  234. train(model)

5、使用paddle.vision中的模型来测试分类

PS:看起来paddle和torch没什么区别

(1)可以直接只用很多模型

from paddle.vision.models import resnet50,vgg16,mobilenet_v3_small,LeNet,GoogLeNet

(2)测试的时候可以直接给定分类和是否使用预训练和直接给定分类个数

    model =resnet50(pretrained=True,num_classes=1)

(3)完整测试代码如下

  1. import cv2
  2. import os
  3. import random
  4. import numpy as np
  5. #已丢弃
  6. # import paddle.fluid as fluid
  7. # from paddle.fluid.dygraph.nn import Conv2D, Pool2D, Linear
  8. import paddle
  9. import paddle.nn.functional as F
  10. from paddle.nn import Conv2D, MaxPool2D, Linear, Dropout
  11. from paddle.vision.models import resnet50,vgg16,mobilenet_v3_small,LeNet,GoogLeNet
  12. """
  13. 数据集iChallenge-PM(眼疾识别)
  14. """
  15. def transform_img(img):
  16. img = cv2.resize(img, (224, 224))
  17. img = np.transpose(img, (2, 0, 1))
  18. img = img.astype('float32')
  19. img = img / 255.
  20. img = img * 2.0 - 1.0
  21. return img
  22. def data_loader(datadir, batch_size=10, mode='train'):
  23. filenames = os.listdir(datadir)
  24. def reader():
  25. if mode == 'train':
  26. random.shuffle(filenames)
  27. batch_imgs = []
  28. batch_labels = []
  29. for name in filenames:
  30. filepath = os.path.join(datadir, name)
  31. img = cv2.imread(filepath)
  32. img = transform_img(img)
  33. if name[0] == 'H':
  34. label = 0
  35. elif name[0] == 'N':
  36. label = 0
  37. elif name[0] == 'P':
  38. label = 1
  39. else:
  40. print('Not excepted file name')
  41. print(name[0])
  42. exit(-1)
  43. batch_imgs.append(img)
  44. batch_labels.append(label)
  45. if len(batch_imgs) == batch_size:
  46. imgs_array = np.array(batch_imgs).astype('float32')
  47. labels_array = np.array(batch_labels).astype(
  48. 'float32').reshape(-1, 1)
  49. yield imgs_array, labels_array
  50. batch_imgs = []
  51. batch_labels = []
  52. if len(batch_imgs) > 0:
  53. imgs_array = np.array(batch_imgs).astype('float32')
  54. labels_array = np.array(batch_labels).astype('float32').reshape(
  55. -1, 1)
  56. yield imgs_array, labels_array
  57. return reader
  58. def valid_data_loader(datadir, csvfile, batch_size=10, mode='valid'):
  59. filelists = open(csvfile).readlines()
  60. def reader():
  61. batch_imgs = []
  62. batch_labels = []
  63. for line in filelists[1:]:
  64. line = line.strip().split(',')
  65. name = line[1]
  66. label = int(line[2])
  67. filepath = os.path.join(datadir, name)
  68. img = cv2.imread(filepath)
  69. img = transform_img(img)
  70. batch_imgs.append(img)
  71. batch_labels.append(label)
  72. if len(batch_imgs) == batch_size:
  73. imgs_array = np.array(batch_imgs).astype('float32')
  74. labels_array = np.array(batch_labels).astype(
  75. 'float32').reshape(-1, 1)
  76. yield imgs_array, labels_array
  77. batch_imgs = []
  78. batch_labels = []
  79. if len(batch_imgs) > 0:
  80. imgs_array = np.array(batch_imgs).astype('float32')
  81. labels_array = np.array(batch_labels).astype('float32').reshape(
  82. -1, 1)
  83. yield imgs_array, labels_array
  84. return reader
  85. DATADIR = 'D:/pytorch_learning2022/data/eye/PALM-Training400'
  86. DATADIR2 = 'D:/pytorch_learning2022/data/eye/PALM-Validation400'
  87. CSCVFILE = 'D:/pytorch_learning2022/data/eye/PM_Label_and_Fovea_Location.csv'
  88. # 定义训练过程
  89. def train(model):
  90. print("---- start training ----")
  91. model.train()
  92. epoch_num = 5
  93. # opt = fluid.optimizer.Momentum(learning_rate=0.001,momentum=0.9, parameter_list=model.parameters())
  94. opt = paddle.optimizer.Momentum(learning_rate=0.001, momentum=0.9, parameters=model.parameters())
  95. train_loader = data_loader(DATADIR, batch_size=10, mode='train')
  96. valid_loader = valid_data_loader(DATADIR2, CSCVFILE)
  97. for epoch in range(epoch_num):
  98. for batch_id, data in enumerate(train_loader()):
  99. x_data, y_data = data
  100. img = paddle.to_tensor(x_data)
  101. label = paddle.to_tensor(y_data)
  102. logits = model(img)
  103. # loss = fluid.layers.sigmoid_cross_entropy_with_logits(logits, label)
  104. loss = F.binary_cross_entropy_with_logits(logits, label) #是否有问题待确认
  105. avg_loss = paddle.mean(loss)
  106. if batch_id % 10 == 0:
  107. print("epoch: {}, batch_id: {}, loss is: {}".format(
  108. epoch, batch_id, avg_loss.numpy()))
  109. avg_loss.backward()
  110. opt.minimize(avg_loss)
  111. model.clear_gradients()
  112. model.eval()
  113. accuracies = []
  114. losses = []
  115. for batch_id, data in enumerate(valid_loader()):
  116. x_data, y_data = data
  117. img = paddle.to_tensor(x_data)
  118. label = paddle.to_tensor(y_data)
  119. logits = model(img)
  120. pred = F.sigmoid(logits)
  121. # loss = fluid.layers.sigmoid_cross_entropy_with_logits(logits, label)
  122. loss = F.binary_cross_entropy_with_logits(logits, label)
  123. pred2 = pred * (-1.0) + 1.0
  124. # pred = fluid.layers.concat([pred2, pred], axis=1)
  125. pred = paddle.concat([pred2, pred], axis=1)
  126. # acc = fluid.layers.accuracy(pred, fluid.layers.cast(label, dtype='int64'))
  127. acc = paddle.metric.accuracy(pred, paddle.cast(label,dtype='int64'))
  128. accuracies.append(acc.numpy())
  129. losses.append(loss.numpy())
  130. print("[validation accuracy/loss: {}/{}]".format(
  131. np.mean(accuracies), np.mean(losses)))
  132. model.train()
  133. # fluid.save_dygraph(model.state_dict(), 'D:/pytorch_learning2022/00_01paddle_learning/result/iChallengePM')
  134. # fluid.save_dygraph(opt.state_dict(), 'D:/pytorch_learning2022/00_01paddle_learning/result/iChallengePM')
  135. paddle.save(model.state_dict(),'palm.pdparams')
  136. paddle.save(opt.state_dict(),'palm.pdopt')
  137. if __name__ == "__main__":
  138. # use_gpu = True
  139. use_gpu = False
  140. paddle.device.set_device('gpu:0') if use_gpu else paddle.device.set_device('cpu')
  141. # model =resnet50()
  142. model =resnet50(pretrained=True,num_classes=1)
  143. train(model)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/92722
推荐阅读
  

闽ICP备14008679号