1. 程式人生 > 實用技巧 >Pytorch和Tensorflow2.0實現mnist_fashion分類

Pytorch和Tensorflow2.0實現mnist_fashion分類

Pytorch:

import torch
from torch import nn
from torch.nn import init
import numpy as np
import sys
from collections import OrderedDict

def load_data_fashion_mnist(batch_size):
import sys
import torch
import torchvision.transforms as transforms
import torchvision
mnist_train = torchvision.datasets.FashionMNIST(root='./Datasets/FashionMNIST', train=True, download=True,
transform=transforms.ToTensor())
mnist_test = torchvision.datasets.FashionMNIST(root='./Datasets/FashionMNIST', train=False, download=True,
transform=transforms.ToTensor())
if sys.platform.startswith('win'):
num_workers = 0 # 0表示不⽤額外的程序來加速讀取資料
else:
num_workers = 4
train_iter = torch.utils.data.DataLoader(mnist_train,
batch_size=batch_size, shuffle=True, num_workers=num_workers)
test_iter = torch.utils.data.DataLoader(mnist_test,
batch_size=batch_size, shuffle=False, num_workers=num_workers)
return train_iter, test_iter

batch_size = 256
train_iter, test_iter = load_data_fashion_mnist(batch_size)

# 定義模型
num_inputs = 784
num_outputs = 10

class LinearNet(nn.Module):
def __init__(self, num_inputs, num_outputs):
super(LinearNet, self).__init__()
self.linear = nn.Linear(num_inputs, num_outputs)
def forward(self, x): # x.shape [batch_size, 1, 28, 28]
y = self.linear(x.view(x.shape[0], -1))
return y
# net = LinearNet(num_inputs, num_outputs)
# 展平操作
class FlattenLayer(nn.Module):
def __init__(self):
super(FlattenLayer, self).__init__()
def forward(self, x):
return x.view(x.shape[0], -1)

net = nn.Sequential(
OrderedDict([
('flatten', FlattenLayer()),
('linear', nn.Linear(num_inputs, num_outputs))
])
)

# 初始化模型的權值引數
init.normal_(net.linear.weight, mean=0, std=0.01)
init.constant_(net.linear.bias, val=0)

# 定義損失函式
loss = nn.CrossEntropyLoss()

# 定義優化演算法
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)

# 訓練模型
num_epochs = 10
def evaluate_accuracy(data_iter, net):
acc_sum, n = 0.0, 0
for X, y in data_iter:
acc_sum += (net(X).argmax(dim=1)==y).float().sum().item()
n += y.shape[0]
return acc_sum / n

def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params=None, lr=None, optimizer=None):
for epoch in range(num_epochs):
train_l_sum, train_acc_sum, n = 0.0, 0.0, 0
for X, y in train_iter:
y_hat = net(X)
l = loss(y_hat, y).sum()

# 梯度清零
if optimizer is not None:
optimizer.zero_grad()
elif params is not None and params[0].grad is not None:
for param in params:
param.grad.data.zero_()

l.backward()
if optimizer is None:
sgd(params, lr, batch_size)
else:
optimizer.step()

train_l_sum += l.item()
train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item()
n += y.shape[0]
test_acc = evaluate_accuracy(test_iter, net)
print('epoch:', epoch, 'loss:', train_l_sum / n, 'train acc:', train_acc_sum / n, 'test acc:', test_acc)


train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size,None, None, optimizer)

TRensorflow2.0:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets, metrics, Sequential, optimizers, layers
import numpy as np
import os

tf.random.set_seed(0)
np.random.seed(0)
os.environ['TF_CPP_MIN_LEVEL'] = '2'
assert tf.__version__.startswith('2.')

batch_size = 256
epochs = 10
optimizer = optimizers.Adam(lr=0.01)

def preprocess(x, y):
x = tf.cast(x, tf.float32) / 255.
y = tf.cast(y, tf.int32)
return x, y

(x_train, y_train), (x_test, y_test) = datasets.fashion_mnist.load_data()
x_train = x_train[:, :, :, np.newaxis]
x_test = x_test[:, :, :, np.newaxis]
# print(x_train.shape, y_train.shape)
train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_db = train_db.map(preprocess).shuffle(60000).batch(batch_size)
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test))
test_db = test_db.map(preprocess).batch(batch_size)

class LinearNet(keras.Model):
def __init__(self):
super(LinearNet, self).__init__()
self.fc = layers.Dense(10)
def call(self, inputs, training=None):
x = inputs
x = tf.reshape(x, (-1, 28*28))
y = self.fc(x)
return y

model = LinearNet()
model.build(input_shape=(None, 28, 28, 1))
model.summary()

# x = tf.random.normal((1, 28, 28, 1))
# out = model(x)
# print(out)

# 模型訓練
def main():
for epoch in range(epochs):
for step, (x, y) in enumerate(train_db):
with tf.GradientTape() as tape:
logits = model(x, training=True)
y_onehot = tf.one_hot(y, depth=10)
loss = tf.losses.categorical_crossentropy(y_onehot, logits, from_logits=True)
loss = tf.reduce_mean(loss)
grads = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))

if step % 100 == 0:
print('epoch:', epoch, 'step:', step, 'loss:', float(loss))

# test
if step % 200 == 0:
total_correct = 0
total_num = 0
for step, (x, y) in enumerate(test_db):
logits = model(x)
prob = tf.nn.softmax(logits, axis=1)
pred = tf.cast(tf.argmax(prob, axis=1), dtype=tf.int32)
correct = tf.reduce_sum(tf.cast(tf.equal(pred, y), dtype=tf.int32))
total_correct += int(correct)
total_num += x.shape[0]

acc = total_correct / total_num
print('epoch:', epoch, 'step:', step, 'acc:', acc)






if __name__ == '__main__':
main()