赞
踩
(1)paddle的API官方地址
Conv2D-API文档-PaddlePaddle深度学习平台
(2)本教程和以下教程不够详细,还是推荐下面这个大佬的blog看一下
计算机视觉——眼疾图片识别(数据集iChallenge-PM)_「已注销」的博客-CSDN博客
(3)blibli视频
252-06_预测病理性近视_图片数据读取_dec_哔哩哔哩_bilibili
(4)数据集地址
眼疾识别数据集iChallenge-PM - 飞桨AI Studio
(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博客
(1)程序测试代码
- import cv2
- import random
- import numpy as np
- import os
- import paddle
- import paddle.nn.functional as F
- from paddle.nn import Conv2D, MaxPool2D, Linear, Dropout
-
- #对读入的图像数据进行预处理
- def transform_img(img):
- #将图片尺寸缩放到 224 * 224
- img = cv2.resize(img, (224,224))
- #读取的图像数据格式是[H, W, C]
- #使用转置操作将其变成[C, H, W]
- img = np.transpose(img,(2,0,1))
- #归一化操作,将数据范围调整到[-1.0, 1.0]之间
- img = img / 255
- img = img * 2.0 -1.0
- return img
-
-
- #定义训练集数据读取器
- def data_loader(datadir, batch_size=10, mode='train'):
- #将datadir目录下的文件列出来,每条文件都读入
- filenames = os.listdir(datadir)
- def reader():
- # print("chen_filenames")
- # print(filenames)
- #只有在训练的时随机打乱数据顺序,测试的时候不打乱
- if mode == 'train':
- random.shuffle(filenames)
- batch_imgs = []
- batch_labels = []
- for name in filenames:
- filepath = os.path.join(datadir,name)
- img = cv2.imread(filepath)
- img = transform_img(img)
- if name[0] == 'H' or name[0] == 'N':
- # H开头的文件名表示高度近似,N开头的文件名表示正常视力
- # 高度近似和正常视力的样板,都不是病理性的,属于负样本,标签为0
- label = 0
- elif name[0] == 'P':
- # P开头的是病理性近似,属于正样本,标签为1
- label = 1
- else:
- raise('Not excepted file name')
- #每读取一个样板的数据,就将其放入数据列表中
- batch_imgs.append(img)
- batch_labels.append(label)
- if len(batch_imgs) == batch_size:
- # 当数据列表的长度等于batch_size的时候
- # 把这些数据当做一个mini-batch,并作为数据生成器的一个输出
- imgs_array = np.array(batch_imgs).astype('float32')
- labels_array = np.array(batch_labels).astype('float32').reshape(-1,1)
- # yield的作用:返回一个可以用来迭代(for循环)的生成器,
- # 它的应用场景通常为一个需要返回一系列值的,含有循环的函数中
- yield imgs_array, labels_array
- batch_imgs = []
- batch_labels = []
-
- #上面都循环结束了,如何还有剩下的,也就是样板数/batch_size数没有整除
- if len(batch_imgs) > 0:
- imgs_array = np.array(batch_imgs).astype('float32')
- labels_array = np.array(batch_labels).astype('float32').reshape(-1,1)
- # yield的作用:返回一个可以用来迭代(for循环)的生成器,
- # 它的应用场景通常为一个需要返回一系列值的,含有循环的函数中
- yield imgs_array, labels_array
-
- return reader
-
-
- EPOCH_NUM = 5
-
- #定义训练过程
- def train_pm(model, optimizer):
- # 开启0号GPU训练
- use_gpu = True
- paddle.device.set_device('gpu:0') if use_gpu else paddle.device.set_device('cpu')
-
- print('start training ...')
- model.train()
- # 定义数据读取器,训练数据读取器和验证数据读取器
- train_loader = data_loader(DATADIR, batch_size=10, mode='train')
- for epoch in range(EPOCH_NUM):
- for batch_id, data in enumerate(train_loader()): #在返回的reader里面调用函数,调用的就是yield中的枚举返回值
- x_data, y_data = data
- img = paddle.to_tensor(x_data)
- label = paddle.to_tensor(y_data)
- # 运行模型进行前向推理计算,得到预测值
- logits = model(img)
- loss = F.binary_cross_entropy_with_logits(logits, label)
- avg_loss = paddle.mean(loss)
-
- if batch_id % 20 == 0:
- print("epoch: {},batch_id: {}, loss is: {:.4f}".format(epoch, batch_id, float(avg_loss.numpy())))
- #反向传播,更新权重,清除梯度
- avg_loss.backward()
- optimizer.step()
-
- #每一个epoch结束都测试一下
- model.eval()
- accuracies = []
- losses = []
- valid_loader = data_loader(DATADIR, batch_size=10, mode='eval')
- for batch_id, data in enumerate(valid_loader()):
- x_data, y_data = data
- img = paddle.to_tensor(x_data)
- label = paddle.to_tensor(y_data)
- #运行模型前向计算,得到预测值
- logits = model(img)
- # 二分类,sigmoid计算后的结果以0.5为阈值分两个类型
- # 计算sigmoid后的预测概率,进行loss计算
- pred = F.sigmoid(logits) # P正的概率
- loss = F.binary_cross_entropy_with_logits(logits,label)
- #计算概率小于0.5的类别
- pred2 = pred*(-1.0) + 1.0 # P负的概率,也就是1-P正
- #得到两个类别的预测概率,并沿第一个维度级联
- pred = paddle.concat([pred2, pred],axis=1)
- #原因是paddle.metric.accuracy的输入要是每个类别的概率,所以拼接了一下
- acc = paddle.metric.accuracy(pred, paddle.cast(label,dtype='int64'))
-
-
- accuracies.append(acc.numpy())
- losses.append(loss.numpy())
- print("[validation] accuracy /loss: {:.4f}/{:.4f}".format(np.mean(accuracies),np.mean(losses))) #求平均
- model.train()
-
- paddle.save(model.state_dict(),'palm.pdparams')
- paddle.save(optimizer.state_dict(),'palm.pdopt')
-
-
- #定义评国过程
- def evaluation(model, params_file_path):
- # 开启0号GPU预估
- use_gpu = True
- paddle.device.set_device('gpu:0') if use_gpu else paddle.device.set_device('cpu')
-
- print('start evaluation ...')
- #加载模型参数
- model_state_dict = paddle.load(params_file_path)
- model.load_dict(model_state_dict)
-
- model.eval()
- eval_loader = data_loader(DATADIR, batch_size=10, mode='eval')
-
- acc_set = []
- avg_loss_set = []
- for batch_id, data in enumerate(eval_loader()):
- x_data, y_data =data
- img = paddle.to_tensor(x_data)
- label = paddle.to_tensor(y_data)
- y_data = y_data.astype(np.int64)
- label_64 = paddle.to_tensor(y_data)
- #计算预测和精度
- #模型的forward方法这两个封装了对img, label_64的判断,如果传入了label,则也返回acc
- prediction, acc = model(img, label_64)
- # 计算损失函数值
- loss = F.binary_cross_entropy_with_logits(prediction, label)
- avg_loss = paddle.mean(loss)
- acc_set.append(float(acc.numpy()))
- avg_loss_set.append(float(avg_loss.numpy()))
-
- #求平均精度
- acc_val_mean = np.array(acc_set).mean()
- avg_loss_val_mean = np.array(avg_loss_set).mean()
-
- print('loss={:.4f}, acc={:.4f}'.format(avg_loss_val_mean,acc_val_mean))
-
-
-
- #定义Lenet网络结果
- # class Lenet(paddle.nn.Layer):
- # pass
-
- # 定义 LeNet 网络结构
- class LeNet(paddle.nn.Layer):
- def __init__(self, num_classes=1):
- super(LeNet, self).__init__()
-
- # 创建卷积和池化层块,每个卷积层使用Sigmoid激活函数,后面跟着一个2x2的池化
- self.conv1 = Conv2D(in_channels=3, out_channels=6, kernel_size=5)
- self.max_pool1 = MaxPool2D(kernel_size=2, stride=2)
- self.conv2 = Conv2D(in_channels=6, out_channels=16, kernel_size=5)
- self.max_pool2 = MaxPool2D(kernel_size=2, stride=2)
- # 创建第3个卷积层
- self.conv3 = Conv2D(in_channels=16, out_channels=120, kernel_size=4)
- # 创建全连接层,第一个全连接层的输出神经元个数为64, 第二个全连接层输出神经元个数为分类标签的类别数
- self.fc1 = Linear(in_features=300000, out_features=64)
- self.fc2 = Linear(in_features=64, out_features=num_classes)
- # 网络的前向计算过程
- def forward(self, x, label=None):
- x = self.conv1(x)
- x = F.sigmoid(x)
- x = self.max_pool1(x)
- x = self.conv2(x)
- x = F.sigmoid(x)
- x = self.max_pool2(x)
- x = self.conv3(x)
- x = F.sigmoid(x)
- x = paddle.reshape(x, [x.shape[0], -1])
- x = self.fc1(x)
- x = self.fc2(x)
- if label is not None:
- acc = paddle.metric.accuracy(input=x,label=label)
- return x,acc
- else:
- return x
-
-
- # 数据的路径
- DATADIR = '/home/chen/deep_data/eye_ill/training/PALM-Training400'
- #创建模型
- model = LeNet(num_classes=1)
- #启动训练过程
- opt = paddle.optimizer.Momentum(learning_rate=0.001,momentum=0.9,
- parameters=model.parameters())
- train_pm(model,optimizer=opt)
- evaluation(model,params_file_path='palm.pdparams')
(2)5个epoch的测试结果
(1)看了一下paddle的api, paddle.fluid已经被丢弃
(2)主要修改注意事项
Conv2D-API文档-PaddlePaddle深度学习平台
class paddle.nn.Conv2D(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, padding_mode='zeros', weight_attr=None, bias_attr=None, data_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的主要的修改对比如下
- self.conv1 = paddle.fluid.dygraph.nn.Conv2D(num_channels=3, num_filters=6, filter_size=5,act='sigmoid')
-
- self.conv1= paddle.nn.Conv2D(in_channels=3,out_channels=6,kernel_size=5) #sigmoid单独在forward中实现
(1)函数说明
MaxPool2D-API文档-PaddlePaddle深度学习平台
paddle.nn.MaxPool2D(kernel_size, stride=None, padding=0, ceil_mode=False, return_mask=False, data_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的主要的修改对比如下
- self.pool1 = paddle.fluid.dygraph.nn.Pool2D(pool_size=2, pool_stride=2, pool_type='max')
-
- self.pool1 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
Linear-API文档-PaddlePaddle深度学习平台
(1)函数定义
class paddle.nn.Linear(in_features, out_features, weight_attr=None, bias_attr=None, name=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的主要的修改对比如下
- self.fc1 = paddle.fluid.dygraph.nn.Linear(input_dim=300000, output_dim=64, act='sigmoid')
-
- self.fc1 = paddle.nn.Linear(in_features=300000, out_features=64)#sigmoid单独在forward中实现
binary_cross_entropy_with_logits-API文档-PaddlePaddle深度学习平台
(1)fluid.layers.sigmoid_cross_entropy_with_logits的定义
(2)paddle.nn.functional.binary_cross_entropy_with_logits的定义
(1)测试代码
- import cv2
- import os
- import random
- import numpy as np
- #已丢弃
- # import paddle.fluid as fluid
- # from paddle.fluid.dygraph.nn import Conv2D, Pool2D, Linear
- import paddle
- import paddle.nn.functional as F
- from paddle.nn import Conv2D, MaxPool2D, Linear, Dropout
-
- """
- 数据集iChallenge-PM(眼疾识别)
- """
-
-
- def transform_img(img):
- img = cv2.resize(img, (224, 224))
- img = np.transpose(img, (2, 0, 1))
- img = img.astype('float32')
- img = img / 255.
- img = img * 2.0 - 1.0
- return img
-
-
- def data_loader(datadir, batch_size=10, mode='train'):
- filenames = os.listdir(datadir)
-
- def reader():
- if mode == 'train':
- random.shuffle(filenames)
- batch_imgs = []
- batch_labels = []
- for name in filenames:
- filepath = os.path.join(datadir, name)
- img = cv2.imread(filepath)
- img = transform_img(img)
- if name[0] == 'H':
- label = 0
- elif name[0] == 'N':
- label = 0
- elif name[0] == 'P':
- label = 1
- else:
- print('Not excepted file name')
- print(name[0])
- exit(-1)
- batch_imgs.append(img)
- batch_labels.append(label)
- if len(batch_imgs) == batch_size:
- imgs_array = np.array(batch_imgs).astype('float32')
- labels_array = np.array(batch_labels).astype(
- 'float32').reshape(-1, 1)
- yield imgs_array, labels_array
- batch_imgs = []
- batch_labels = []
- if len(batch_imgs) > 0:
- imgs_array = np.array(batch_imgs).astype('float32')
- labels_array = np.array(batch_labels).astype('float32').reshape(
- -1, 1)
- yield imgs_array, labels_array
-
- return reader
-
-
- def valid_data_loader(datadir, csvfile, batch_size=10, mode='valid'):
- filelists = open(csvfile).readlines()
-
- def reader():
- batch_imgs = []
- batch_labels = []
- for line in filelists[1:]:
- line = line.strip().split(',')
- name = line[1]
- label = int(line[2])
- filepath = os.path.join(datadir, name)
- img = cv2.imread(filepath)
- img = transform_img(img)
- batch_imgs.append(img)
- batch_labels.append(label)
- if len(batch_imgs) == batch_size:
- imgs_array = np.array(batch_imgs).astype('float32')
- labels_array = np.array(batch_labels).astype(
- 'float32').reshape(-1, 1)
- yield imgs_array, labels_array
- batch_imgs = []
- batch_labels = []
- if len(batch_imgs) > 0:
- imgs_array = np.array(batch_imgs).astype('float32')
- labels_array = np.array(batch_labels).astype('float32').reshape(
- -1, 1)
- yield imgs_array, labels_array
-
- return reader
-
-
- DATADIR = 'D:/pytorch_learning2022/data/eye/PALM-Training400'
- DATADIR2 = 'D:/pytorch_learning2022/data/eye/PALM-Validation400'
- CSCVFILE = 'D:/pytorch_learning2022/data/eye/PM_Label_and_Fovea_Location.csv'
-
-
- # 定义LeNet的网络结构
- class LeNet(paddle.nn.Layer):
- def __init__(self, name_scope, num_classes=1):
- super(LeNet, self).__init__(name_scope)
-
- # self.conv1 = paddle.fluid.dygraph.nn.Conv2D(num_channels=3, num_filters=6, filter_size=5,act='sigmoid')
- # self.conv1= paddle.nn.Conv2D(in_channels=3,out_channels=6,kernel_size=5) #sigmoid单独在forward中实现
- self.conv1= Conv2D(in_channels=3,out_channels=6,kernel_size=5) #sigmoid单独在forward中实现
- # self.pool1 = paddle.fluid.dygraph.nn.Pool2D(pool_size=2, pool_stride=2, pool_type='max')
- # self.pool1 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
- self.pool1 = MaxPool2D(kernel_size=2, stride=2)
-
- # self.conv2 = Conv2D(num_channels=6,num_filters=16,filter_size=5,act='sigmoid')
- self.conv2= Conv2D(in_channels=6,out_channels=16,kernel_size=5) #sigmoid单独在forward中实现
- # self.pool2 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
- self.pool2 = MaxPool2D(kernel_size=2, stride=2)
- # self.conv3 = Conv2D(num_channels=16,num_filters=120, filter_size=4, act='sigmoid')
- self.conv3= Conv2D(in_channels=16,out_channels=120,kernel_size=4) #sigmoid单独在forward中实现
-
- # self.fc1 = paddle.fluid.dygraph.nn.Linear(input_dim=300000, output_dim=64, act='sigmoid')
- # self.fc1 = paddle.nn.Linear(in_features=300000, out_features=64)#sigmoid单独在forward中实现
- self.fc1 = Linear(in_features=300000, out_features=64) #sigmoid单独在forward中实现
- # self.fc2 = Linear(input_dim=64, output_dim=num_classes)
- self.fc2 = Linear(in_features=64, out_features=num_classes)
-
- def forward(self, x):
- x = self.conv1(x)
- x = F.sigmoid(x)
- x = self.pool1(x)
-
- x = self.conv2(x)
- x = F.sigmoid(x)
- x = self.pool2(x)
- x = self.conv3(x)
- x = F.sigmoid(x)
-
- # x = fluid.layers.reshape(x, [x.shape[0], -1])
- x = paddle.reshape(x, [x.shape[0], -1])
- x = self.fc1(x)
- x = F.sigmoid(x)
- x = self.fc2(x)
- return x
-
-
- # 定义AlexNet网络结构
- class AlexNet(paddle.nn.Layer):
- def __init__(self, name_scope, num_classes=1):
- super(AlexNet, self).__init__(name_scope)
- name_scope = self.full_name
- # self.conv1 = Conv2D(num_channels=3, num_filters=96,filter_size=11, stride=4, padding=5,act='relu')
- self.conv1= Conv2D(in_channels=3,out_channels=96,kernel_size=5,stride=4,padding=5) #relu单独在forward中实现
- # self.pool1 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
- self.pool1 = MaxPool2D(kernel_size=2, stride=2)
-
- # self.conv2 = Conv2D(num_channels=96,num_filters=256,filter_size=5,stride=1,padding=2, act='relu')
- self.conv2= Conv2D(in_channels=96,out_channels=256,kernel_size=5,stride=1,padding=2) #relu单独在forward中实现
- # self.pool2 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
- self.pool2 = MaxPool2D(kernel_size=2, stride=2)
-
- # self.conv3 = Conv2D(num_channels=256,num_filters=384,filter_size=3,stride=1,padding=1,act='relu')
- self.conv3 = Conv2D(in_channels=256,out_channels=384,kernel_size=3,stride=1,padding=1) #relu单独在forward中实现
- # self.conv4 = Conv2D(num_channels=384,num_filters=384,filter_size=3,stride=1,padding=1,act='relu')
- self.conv4 = Conv2D(in_channels=384,out_channels=384,kernel_size=3,stride=1,padding=1) #relu单独在forward中实现
- # self.conv5 = Conv2D(num_channels=384,num_filters=256,filter_size=3,stride=1,padding=1,act='relu')
- self.conv5 = Conv2D(in_channels=384,out_channels=256,kernel_size=3,stride=1,padding=1) #relu单独在forward中实现
- # self.pool5 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
- self.pool5 = MaxPool2D(kernel_size=2, stride=2)
-
- # self.fc1 = Linear(input_dim=12544, output_dim=4096, act='relu')
- self.fc1 = Linear(in_features=12544, out_features=4096) #relu单独在forward中实现
- self.drop_ratio1 = 0.5
- # self.fc2 = Linear(input_dim=4096, output_dim=4096, act='relu')
- self.fc2 = Linear(in_features=4096, out_features=4096) #relu单独在forward中实现
- self.drop_ratio2 = 0.5
- # self.fc3 = Linear(input_dim=4096, output_dim=num_classes)
- self.fc3 = Linear(in_features=4096, out_features=num_classes)
-
- def forward(self, x):
- x = self.conv1(x)
- x = F.relu(x)
- x = self.pool1(x)
- x = self.conv2(x)
- x = F.relu(x)
- x = self.pool2(x)
- x = self.conv3(x)
- x = F.relu(x)
- x = self.conv4(x)
- x = F.relu(x)
- x = self.conv5(x)
- x = F.relu(x)
- x = self.pool5(x)
-
- # x = fluid.layers.reshape(x, [x.shape[0], -1])
- x = paddle.reshape(x, [x.shape[0], -1])
- x = self.fc1(x)
- x = F.relu(x)
- x = F.dropout(x, self.drop_ratio1)
- x = self.fc2(x)
- x = F.relu(x)
- x = F.dropout(x, self.drop_ratio2)
- x = self.fc3(x)
- return x
-
-
- # 定义训练过程
- def train(model):
- print("---- start training ----")
- model.train()
- epoch_num = 5
- # opt = fluid.optimizer.Momentum(learning_rate=0.001,momentum=0.9, parameter_list=model.parameters())
- opt = paddle.optimizer.Momentum(learning_rate=0.001, momentum=0.9, parameters=model.parameters())
-
- train_loader = data_loader(DATADIR, batch_size=10, mode='train')
- valid_loader = valid_data_loader(DATADIR2, CSCVFILE)
- for epoch in range(epoch_num):
- for batch_id, data in enumerate(train_loader()):
- x_data, y_data = data
- img = paddle.to_tensor(x_data)
- label = paddle.to_tensor(y_data)
- logits = model(img)
- # loss = fluid.layers.sigmoid_cross_entropy_with_logits(logits, label)
- loss = F.binary_cross_entropy_with_logits(logits, label) #是否有问题待确认
- avg_loss = paddle.mean(loss)
-
- if batch_id % 10 == 0:
- print("epoch: {}, batch_id: {}, loss is: {}".format(
- epoch, batch_id, avg_loss.numpy()))
- avg_loss.backward()
- opt.minimize(avg_loss)
- model.clear_gradients()
-
- model.eval()
- accuracies = []
- losses = []
- for batch_id, data in enumerate(valid_loader()):
- x_data, y_data = data
- img = paddle.to_tensor(x_data)
- label = paddle.to_tensor(y_data)
- logits = model(img)
- pred = F.sigmoid(logits)
- # loss = fluid.layers.sigmoid_cross_entropy_with_logits(logits, label)
- loss = F.binary_cross_entropy_with_logits(logits, label)
-
- pred2 = pred * (-1.0) + 1.0
- # pred = fluid.layers.concat([pred2, pred], axis=1)
- pred = paddle.concat([pred2, pred], axis=1)
- # acc = fluid.layers.accuracy(pred, fluid.layers.cast(label, dtype='int64'))
- acc = paddle.metric.accuracy(pred, paddle.cast(label,dtype='int64'))
- accuracies.append(acc.numpy())
- losses.append(loss.numpy())
- print("[validation accuracy/loss: {}/{}]".format(
- np.mean(accuracies), np.mean(losses)))
- model.train()
- # fluid.save_dygraph(model.state_dict(), 'D:/pytorch_learning2022/00_01paddle_learning/result/iChallengePM')
- # fluid.save_dygraph(opt.state_dict(), 'D:/pytorch_learning2022/00_01paddle_learning/result/iChallengePM')
- paddle.save(model.state_dict(),'palm.pdparams')
- paddle.save(opt.state_dict(),'palm.pdopt')
-
- if __name__ == "__main__":
- # use_gpu = True
- use_gpu = False
- paddle.device.set_device('gpu:0') if use_gpu else paddle.device.set_device('cpu')
- # with fluid.dygraph.guard():
- # model = LeNet("LeNet")
- # model = AlexNet("AlexNet")
-
-
- # model = LeNet("LeNet")
- model = AlexNet("AlexNet")
- train(model)
-
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)完整测试代码如下
- import cv2
- import os
- import random
- import numpy as np
- #已丢弃
- # import paddle.fluid as fluid
- # from paddle.fluid.dygraph.nn import Conv2D, Pool2D, Linear
- import paddle
- import paddle.nn.functional as F
- from paddle.nn import Conv2D, MaxPool2D, Linear, Dropout
- from paddle.vision.models import resnet50,vgg16,mobilenet_v3_small,LeNet,GoogLeNet
-
-
- """
- 数据集iChallenge-PM(眼疾识别)
- """
-
-
- def transform_img(img):
- img = cv2.resize(img, (224, 224))
- img = np.transpose(img, (2, 0, 1))
- img = img.astype('float32')
- img = img / 255.
- img = img * 2.0 - 1.0
- return img
-
-
- def data_loader(datadir, batch_size=10, mode='train'):
- filenames = os.listdir(datadir)
-
- def reader():
- if mode == 'train':
- random.shuffle(filenames)
- batch_imgs = []
- batch_labels = []
- for name in filenames:
- filepath = os.path.join(datadir, name)
- img = cv2.imread(filepath)
- img = transform_img(img)
- if name[0] == 'H':
- label = 0
- elif name[0] == 'N':
- label = 0
- elif name[0] == 'P':
- label = 1
- else:
- print('Not excepted file name')
- print(name[0])
- exit(-1)
- batch_imgs.append(img)
- batch_labels.append(label)
- if len(batch_imgs) == batch_size:
- imgs_array = np.array(batch_imgs).astype('float32')
- labels_array = np.array(batch_labels).astype(
- 'float32').reshape(-1, 1)
- yield imgs_array, labels_array
- batch_imgs = []
- batch_labels = []
- if len(batch_imgs) > 0:
- imgs_array = np.array(batch_imgs).astype('float32')
- labels_array = np.array(batch_labels).astype('float32').reshape(
- -1, 1)
- yield imgs_array, labels_array
-
- return reader
-
-
- def valid_data_loader(datadir, csvfile, batch_size=10, mode='valid'):
- filelists = open(csvfile).readlines()
-
- def reader():
- batch_imgs = []
- batch_labels = []
- for line in filelists[1:]:
- line = line.strip().split(',')
- name = line[1]
- label = int(line[2])
- filepath = os.path.join(datadir, name)
- img = cv2.imread(filepath)
- img = transform_img(img)
- batch_imgs.append(img)
- batch_labels.append(label)
- if len(batch_imgs) == batch_size:
- imgs_array = np.array(batch_imgs).astype('float32')
- labels_array = np.array(batch_labels).astype(
- 'float32').reshape(-1, 1)
- yield imgs_array, labels_array
- batch_imgs = []
- batch_labels = []
- if len(batch_imgs) > 0:
- imgs_array = np.array(batch_imgs).astype('float32')
- labels_array = np.array(batch_labels).astype('float32').reshape(
- -1, 1)
- yield imgs_array, labels_array
-
- return reader
-
-
- DATADIR = 'D:/pytorch_learning2022/data/eye/PALM-Training400'
- DATADIR2 = 'D:/pytorch_learning2022/data/eye/PALM-Validation400'
- CSCVFILE = 'D:/pytorch_learning2022/data/eye/PM_Label_and_Fovea_Location.csv'
-
-
-
- # 定义训练过程
- def train(model):
- print("---- start training ----")
- model.train()
- epoch_num = 5
- # opt = fluid.optimizer.Momentum(learning_rate=0.001,momentum=0.9, parameter_list=model.parameters())
- opt = paddle.optimizer.Momentum(learning_rate=0.001, momentum=0.9, parameters=model.parameters())
-
- train_loader = data_loader(DATADIR, batch_size=10, mode='train')
- valid_loader = valid_data_loader(DATADIR2, CSCVFILE)
- for epoch in range(epoch_num):
- for batch_id, data in enumerate(train_loader()):
- x_data, y_data = data
- img = paddle.to_tensor(x_data)
- label = paddle.to_tensor(y_data)
- logits = model(img)
- # loss = fluid.layers.sigmoid_cross_entropy_with_logits(logits, label)
- loss = F.binary_cross_entropy_with_logits(logits, label) #是否有问题待确认
- avg_loss = paddle.mean(loss)
-
- if batch_id % 10 == 0:
- print("epoch: {}, batch_id: {}, loss is: {}".format(
- epoch, batch_id, avg_loss.numpy()))
- avg_loss.backward()
- opt.minimize(avg_loss)
- model.clear_gradients()
-
- model.eval()
- accuracies = []
- losses = []
- for batch_id, data in enumerate(valid_loader()):
- x_data, y_data = data
- img = paddle.to_tensor(x_data)
- label = paddle.to_tensor(y_data)
- logits = model(img)
- pred = F.sigmoid(logits)
- # loss = fluid.layers.sigmoid_cross_entropy_with_logits(logits, label)
- loss = F.binary_cross_entropy_with_logits(logits, label)
-
- pred2 = pred * (-1.0) + 1.0
- # pred = fluid.layers.concat([pred2, pred], axis=1)
- pred = paddle.concat([pred2, pred], axis=1)
- # acc = fluid.layers.accuracy(pred, fluid.layers.cast(label, dtype='int64'))
- acc = paddle.metric.accuracy(pred, paddle.cast(label,dtype='int64'))
- accuracies.append(acc.numpy())
- losses.append(loss.numpy())
- print("[validation accuracy/loss: {}/{}]".format(
- np.mean(accuracies), np.mean(losses)))
- model.train()
- # fluid.save_dygraph(model.state_dict(), 'D:/pytorch_learning2022/00_01paddle_learning/result/iChallengePM')
- # fluid.save_dygraph(opt.state_dict(), 'D:/pytorch_learning2022/00_01paddle_learning/result/iChallengePM')
- paddle.save(model.state_dict(),'palm.pdparams')
- paddle.save(opt.state_dict(),'palm.pdopt')
-
- if __name__ == "__main__":
- # use_gpu = True
- use_gpu = False
- paddle.device.set_device('gpu:0') if use_gpu else paddle.device.set_device('cpu')
- # model =resnet50()
- model =resnet50(pretrained=True,num_classes=1)
- train(model)
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。