近期任务,把论文中用Tensorflow实现的源码转换成Pytorch,菜鸡开始好好撸代码惹。。。
最开始进入Tensorflow中文社区和Pytorch中文社区过了一遍,发现没有特别能记住什么,还是看些基础的例子,然后动手实践起来,期间推荐看相关框架的英文tutorials查阅(可以看看常用词和提高英语,是吧)
Tensorflow英文教程:Tensorflow tutorials
Tensorflow中文教程:Tensorflow 中文
Pytorch英文教程: Pytorch tutorials
Pytorch中文教程:Pytorch 中文
首先做的是搭建CNN
1、Tensorflow搭建CNN:
#coding=UTF-8
#step 1 导入Tensorflow
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
#step 2 加载数据集mnist
mnist = input_data.read_data_sets('MNIST_data/',one_hot=True)
x = tf.placeholder(tf.float32,[None,784])
y_ = tf.placeholder(tf.float32,[None,10])
#step 3 为了代码整洁,定义weight和bias的初始化封装成函数
#通常使用少量的噪声初始化权值以打破对称性,并防止梯度为0
def weight_variable(shape):
initial = tf.truncated_normal(shape,stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
initial = tf.constant(0.1,shape=shape)
return tf.Variable(initial)
#step4 定义卷积层和maxpooling
#为了代码整洁,将卷积层和maxpooling封装起来
def conv2d(x,w):
return tf.nn.conv2d(x,w,strides=[1,1,1,1],padding='SAME')
def max_pool_2x2(x):
return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
#step5 reshape image数据
x_image = tf.reshape(x,[-1,28,28,1])
#step6 搭建第一个卷积层
#使用32个5x5的filter,然后通过maxpooling
W_conv1 = weight_variable([5,5,1,32])
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)
h_pool1 = max_pool_2x2(h_conv1)
#step7 搭建第二个卷积层
#使用64个5x5的filter
W_conv2 = weight_variable([5,5,32,64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1,W_conv2)+b_conv2)
h_pool2 = max_pool_2x2(h_conv2)
#step8 构建全连接层
#需要将上一层的输出展开成1d的神经层
W_fc1 = weight_variable([7*7*64,1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2,[-1,7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat,W_fc1)+b_fc1)
#step9 添加Dropout
#加入Dropout层,可以防止过拟合问题,这里使用了一个Placeholder,控制在训练和测试时候是否使用Dropout层
keep_prob = tf.placeholder(tf.float32)
h_fc1_dropout = tf.nn.dropout(h_fc1,keep_prob)
#step10 输入层 输出一个线性结果
W_fc2 = weight_variable([1024,10])
b_fc2 = bias_variable([10])
y_conv = tf.matmul(h_fc1_dropout,W_fc2)+b_fc2
#step11 训练和评估
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_,
logits=y_conv))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(y_,1),tf.argmax(y_conv,1)),tf.float32))
with tf.Session() as sess:
writer = tf.summary.FileWriter('logs/', sess.graph)
tf.global_variables_initializer().run()
for i in range(3000):
batch = mnist.train.next_batch(50)
if i%100 == 0:
train_accuracy = accuracy.eval(feed_dict = {x:batch[0],
y_:batch[1],
keep_prob:1.})
print('steo {},the train accuracy {}'.format(i,train_accuracy))
train_step.run(feed_dict={x:batch[0],y_:batch[1],keep_prob:0.5})
test_accuracy = accuracy.eval(feed_dict = {x:mnist.test.images,y_:mnist.test.labels,
keep_prob:1.})
print('the test accuracy :{}'.format(test_accuracy))
saver = tf.train.Saver()
path = saver.save(sess,'./results/mnist_deep.ckpt')
print('save path:{}'.format(path))
2、Pytorch搭建CNN:
#coding=UTF-8
#导入需要的包
import torch
import torch.nn as nn
import torchvision.datasets as normal_datasets
import torchvision.transforms as transforms
from torch.autograd import Variable
import matplotlib.pyplot as plt
#超参
EPOCH = 1
BATCH_SIZE = 100
LR = 0.001
#将数据处理成Variable,如果有GPU,可以转换成cuda形式
def get_variable(x):
x = Variable(x)
return x.cuda() if torch.cuda.is_available() else x
#从torchvision.datasets中加载一些常用的数据集
train_dataset = normal_datasets.MNIST(
root='./mnist/',
train=True,
transform=transforms.ToTensor(),
download=True
)
#绘制图
print(train_dataset.train_data.size())
print(train_dataset.train_labels.size())
plt.imshow(train_dataset.train_data[0].numpy(),cmap='gray')
plt.title('%i' % train_dataset.train_labels[0])
plt.show()
#建立数据加载器和batch
test_datatest = normal_datasets.MNIST(
root='./mnist/',
train=True,
transform=transforms.ToTensor(),
)
#处理数据,使用DataLoader进行batch训练
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
batch_size=BATCH_SIZE,
shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=test_datatest,
batch_size=BATCH_SIZE,
shuffle=False)
#建立计算图模型
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
#使用序列工具快速构建
self.conv1 = nn.Sequential(
nn.Conv2d(1,16,kernel_size=5,padding=2),
nn.BatchNorm2d(16),
nn.ReLU(),
nn.MaxPool2d(2)
)
self.conv2 = nn.Sequential(
nn.Conv2d(16,32,kernel_size=5,padding=2),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.MaxPool2d(2)
)
self.fc = nn.Linear(7*7*32,10)
def forward(self,x):
out = self.conv1(x)
out = self.conv2(out)
out = out.view(out.size(0),-1)
out = self.fc(out)
return out
cnn = CNN()
print(cnn)
if torch.cuda.is_available():
cnn = cnn.cuda()
#定义优化器和损失(选择损失函数和优化方法)
loss_func = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(cnn.parameters(),lr=LR)
#进行batch训练
for epoch in range(EPOCH):
for i,(images,labels) in enumerate(train_loader):
images = get_variable(images)
labels = get_variable(labels)
# 输入训练数据
outputs = cnn(images)
#计算误差
loss = loss_func(outputs,labels)
# 清空上一次的梯度
optimizer.zero_grad()
# 误差反向传递
loss.backward()
# 优化器参数更新
optimizer.step()
if(i+1)%100 ==0:
print('Epoch [%d/%d], Iter [%d/%d] Loss: %.4f'
% (epoch + 1, EPOCH, i + 1, len(train_dataset) //BATCH_SIZE, loss.data[0]))
#测试模型
cnn.eval()
correct = 0
total = 0
for images,labels in test_loader:
images = get_variable(images)
labels = get_variable(labels)
outputs = cnn(images)
_,predicted = torch.max(outputs.data,1)
total += labels.size(0)
correct += (predicted == labels.data).sum()
#print('测试准确率: %d%d' %(100*correct/total))
print(' 测试 准确率: %d %%' % (100 * correct / total))
#保存训练模型
torch.save(cnn.state_dict(),'cnn.pkl')