作者:tequilaro
本文主要讲解pytorch的整个使用流程,因楼主之前一直使用caffe进行深度学习开发,但是caffe框架改动起来不是很方便所以在前不久转型为pytorch。最主要是记录自己的学习历程,理清思路,以便更好地研究,如果大家还有什么好的建议,希望可以提出来。
pytorch的操作简单,一般只需要一个文件即可,相对而言没有之前caffe那么复杂。
从数据的收集、模型的搭建、接着不断调参训练模型、最终得到结果。楼主之前一直使用caffe进行深度学习开发,但是在修改卷积核的时候遇到一些问题,我一直是针对石油随钻数据来进行深度学习研究,输入的随钻数据是5*5的矩阵,之前是采用3*3的卷积核进行卷积,但是后期发现因为我的每行数据对应一个完整的特征,所以应该采用非对称卷积核,但是caffe却没有办法设置非对称卷积核,所以果断转为了pytorch,放弃caffe。
这里分享一个关于卷积后H与W的计算公式。
W/H=[(输入大小-卷积核大小+2*P)/步长] +1.
(注意:卷积向下取整,池化向上取整。)
- 数据读取
然后就是进行数据的读取,楼主的数据是600*5,之后利用滑动窗口法将其变为了596*5*5的数据,也就是596个5*5的矩阵,然后pytorch输入的数据类型为N*C*H*W,所以按照此类型创建一个给定形状和类型的用0填充的数组;然后再将利用np.loadtxt加载txt文件,再将numpy数据转为tensor。下面是数据读取的代码。
X = np.zeros((596, 1, 5, 5), dtype=np.float32)
Y = np.zeros(596, dtype=np.int64)
a = np.loadtxt("data_5.txt")
for row in range(0, 596):
col1 = row
col2 = row + 5
X[row][0] = a[col1:col2]
b = np.loadtxt("label.txt")
for i in range(596):
Y[i] = b[i]
data_x = torch.from_numpy(X)
data_y = torch.from_numpy(Y)
train_dataset = dataf.TensorDataset(data_x, data_y)
train_loader = dataf.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
###这是数据的读取代码。
- 网络定义
这里主要用到了非对称卷积核。
class CONV_NET(torch.nn.Module): #CONV_NET类继承nn.Module类
def __init__(self):
super(CONV_NET, self).__init__() #使CONV_NET类包含父类nn.Module的所有属性
# super()需要两个实参,子类名和对象self
self.conv1 = nn.Conv2d(1, 32, (2, 5), 1, padding=0)
self.conv2 = nn.Conv2d(32, 128, 1, 1, padding=0)
self.fc1 = nn.Linear(512, 128)
self.relu1 = nn.ReLU(inplace=True)
self.drop1 = nn.Dropout(0.5)
self.fc2 = nn.Linear(128, 32)
self.relu2 = nn.ReLU(inplace=True)
self.fc3 = nn.Linear(32, 3)
self.softmax = nn.Softmax(dim=1)
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = x.view(x.size(0), -1)
x = self.fc1(x)
x = self.relu1(x)
x = self.drop1(x)
x = self.fc2(x)
x = self.relu2(x)
x = self.fc3(x)
x = self.softmax(x)
return x
batch_size = 6
learning_rate = 0.0001
num_epoches = 200
model = CONV_NET()
model = model.cuda()
- 定义损失函数以及迭代次数
for epoch in range(num_epoches):
model.train()
train_loss = 0.0
train_acc = 0.0
# 每次输入batch_idx个数据
for batch_idx, data in enumerate(train_loader):
# 加载数据
img, label = data
img, label = img.cuda(), label.cuda()
# optimizer.zero_grad()
out = model(img)
# 计算损失
loss = criterion(out, label)
train_loss += loss.item()
# 计算准确率
pred = torch.max(out, 1)[1]
train_correct = (pred == label).sum()
train_acc += train_correct.item()
# 回传并更新梯度
optimizer.zero_grad()
loss.backward()
optimizer.step()
print('Train Epoch: {} \t### Total_Loss: {:.6f}\t TotalAcc: {:.3f}% ###'.format(epoch + 1, train_loss / (len(train_dataset)),
100. * train_acc / (len(train_dataset))
)
)
torch.save(model.state_dict(), './model/' + str(epoch) + '_params.pkl')
print('--------------------------------------------------------')
Loss_list.append(train_loss / (len(train_dataset)))
file = open("Loss.txt", "w")
file.write(str(Loss_list))
file.close()
Accuracy_list.append(100 * train_acc / (len(train_dataset)))
file1 = open("Accuracy.txt", "w")
file1.write(str(Accuracy_list))
file1.close()
print('finish training!')
这样就是我的pytorch的入门教程。
主要是为了将自己的数据作为测试数据放入模型网络中输出决策。
这里涉及到模型的保存和加载。
在pytorch里使用torch.save来保存模型的结构和参数。
加载模型同样也有两种方式。
model.load_state_dict(torch.load(‘params.pkl’))
model = torch.load(‘./model/epoch_190.pth’)
model.eval()
with torch.no_grad():
for i in range(2):
print(data_x[i])
output = model(data_x[i].unsqueeze(0).cuda())
pred = torch.max(output,1)[1]
print(pred)
print('----------------------------------------------')