不调用torch.nn中函数,自己实现cnn的功能进行mnist手写体识别

import torchvision.transforms
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from torchvision import datasets
import numpy as np
import matplotlib.pyplot as plt

# 1.导入mnist数据集
train_dataset = datasets.MNIST(root="./data", train=True, transform=torchvision.transforms.ToTensor(), download=True)
test_dataset = datasets.MNIST(root="./data", train=False, transform=torchvision.transforms.ToTensor(), download=True)
train_data_size = len(train_dataset)
test_data_size = len(test_dataset)
# 2.加载数据集
train_loader = DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=64, shuffle=True)


# 定义一个学习率
learning_rate = 0.001
epochs = 5
batch_size=1024

# # 测试一下数据集的形状
# for data in test_loader:
#     imgs,lables = data
#     print(imgs)
#     print(imgs.shape)
#     print(lables)
#     print(lables.shape)

# .对x进行标准化,把输入控制在[0,1]
def Normaliza(x):
    # 计算均值
    x_mean = np.mean(x)
    # 计算标准差
    x_std = np.std(x)
    # 最后将输入控制在[0,1]之间
    X = (x - x_mean) / x_std
    return X


# # 定义sigmoid激活函数diff == True 为要求导
# def Sigmoid(x):
#     # sigmoid函数
#     return 1.0 / (1.0 + np.exp(-x))

# 定义一个softmax来计算y_hat
def softmax(x,w,b):
    y_hat = np.dot(x,w) + b

    y_exp = np.exp(y_hat)
    y_hat = y_exp / np.sum(y_exp, axis=1, keepdims=True)
    return y_hat

# # 定义交叉熵损失函数
# def CrossEntropyLoss(y, y_):
#     return - np.sum(y * np.log(y_) + (1 - y) * np.log(1 - y_))


# 制作只有0和1的数据
def make_one_hot(data):
    return (np.arange(10) == data[:, None]).astype(np.integer)

# def loss(w,x,y,y_hat):
#     rows = x.shape[0]
#     reg_loss = 0.5 * 1e-3 * np.sum(w * w)  # 正则化
#
#     cost = -np.sum(y * np.log(y_hat)) / rows
#     cost += reg_loss
#     return cost

# 定义梯度下降函数进行参数的更新
def grad_desc(x,y,w,b,learning_rate):
    # 1.计算y_hat
    y_hat = softmax(x,w,b)
    # 计算损失函数
    rows = x.shape[0]  # x.shape[0]为x的行数

    # 计算损失值
    reg_loss = 0.5 * 1e-3 * np.sum(w * w)  # 正则化

    cost = -np.sum(y * np.log(y_hat)) / rows
    cost += reg_loss

    # 更新参数w和b
    g_w = np.dot(x.T, (y_hat - y)) / rows
    g_w += 1e-3 * w
    g_b = np.sum((y_hat - y),axis=0) / rows

    # 添加学习率改变梯度下降的速度
    w -= g_w * learning_rate
    b -= g_b * learning_rate
    return w,b,cost

# 初始化w和b
w = np.random.randn(784,10)/np.sqrt(784)
b = np.zeros((1,10))    # 应该是一行十列[[0.],[0.]...[0.]]
loss = 0

writer = SummaryWriter("log")
total_train_step = 0
# 开始训练数据
train_loss = []
test_loss = []
train_acc = []
test_acc = []
for epoch in range(epochs):
    print("------第{}轮训练开始------".format(epoch+1))
    # 训练数据集上
    total_accuracy = 0
    total_train_loss = 0
    for data in train_loader:
        x_train, y_train = data  # x_train(64,1,28,28)
        X_train = x_train.squeeze().numpy() #X_train(64,28,28),去掉一维的数据,并将Tensor类型转换为ndarray类型
        X_train = X_train.reshape(X_train.shape[0],-1)# 调整X_train的形状大小为(64,,28*28)
        X_train = Normaliza(X_train)  # 对X_train进行归一化数据处理

        y_train = y_train.numpy()                     #(64,)
        Y_train = make_one_hot(y_train)
        # 使用grad_sec对参数w,b的更新,并计算loss值
        w, b, loss = grad_desc(X_train, Y_train, w, b, learning_rate)
        # 计算y_pred
        y_pred = softmax(X_train,w,b)
        y_pred = np.argmax(y_pred,axis=1)   #axis = 0按行计算,得到列的性质。axis = 1按列计算,得到行的性质
        # 计算准确率
        accuracy = (y_pred == y_train).sum()
        total_accuracy += accuracy
        total_train_loss += loss
    train_loss.append(total_train_loss/train_data_size)
    train_acc.append(total_accuracy / train_data_size)
        # if total_train_step % 100 == 0:
    print("训练次数:{},loss:{:.4f},train_accuracy:{:.2f}%".format(total_train_step+1, total_train_loss/train_data_size, 100*total_accuracy / train_data_size))



    total_acc_test = 0
    total_test_loss = 0
    # 测试数据集上
    for data in test_loader:
        x_test, y_test = data
        X_test = x_test.squeeze().numpy()
        X_test = X_test.reshape(X_test.shape[0], -1)
        X_test = Normaliza(X_test)

        y_test = y_test.numpy()

        # 计算y_test_pred,并计算正确率
        y_test_pred = softmax(X_test,w,b)
        # 计算loss
        reg_loss = 0.5 * 1e-3 * np.sum(w * w)  # 正则化
        Y_test = make_one_hot(y_test)
        test_cost = -np.sum(Y_test * np.log(y_test_pred)) / X_test.shape[0]
        test_cost += reg_loss

        y_test_pred = np.argmax(y_test_pred, axis=1)
        acc_test = (y_test_pred == y_test).sum()
        total_acc_test += acc_test
        total_test_loss += test_cost
    test_loss.append(total_test_loss/test_data_size)
    test_acc.append(total_acc_test/test_data_size)

    print("整体测试集上loss:{:.4f},的正确率:{:.2f}%".format(total_test_loss/test_data_size, 100*total_acc_test/test_data_size))
    # writer.add_scalars("loss",{"train":total_train_loss/train_data_size,"test":total_test_loss/test_data_size},total_train_step)
    # writer.add_scalars("accuracy",{"train_accuracy": 100*total_accuracy / train_data_size, "test_accuracy": 100*total_acc_test/test_data_size}, total_train_step)
    total_train_step += 1

x = range(epochs)
ax = plt.gca()
plt.plot(x,train_loss,'b',label="Train_loss")
plt.plot(x,test_loss,'r',label="test_loss")
plt.title("Train and Test loss")
plt.legend(loc='upper left')
plt.figure()

plt.plot(x,train_acc,'b',label="Train_accuracy")
plt.plot(x,test_acc,'r',label="Test_accuracy")
plt.title("Train and Test accuracy")
plt.legend(loc="lower right")
plt.show()




















# 定义模型
# class model():
#     def __init__(self):
#         # 随机化定义Input X的形状
#         self.X = np.random.randn(1024, 1)
#         self.W = np.random.randn(10, 1024)  # 随机化W的值
#         self.b = np.random.randn(10, 1)     # 随机化b的值
#         self.learningrate = 0.01            # 学习率
#
#     # 前向传播
#     def forward(self, X, y, activate): # activate是激活函数
#         self.X = X
#         self.z = np.dot(self.W, self.X) + self.b  # z=w点乘x+b
#         self.y_hat = activate(self.z)             # z=sigmoid(z)
#         loss = SquareErrorSum(self.y_hat, y)    # 通过y,y_hat 计算损失函数
#         return loss, self.y_hat                   # 返回损失值,和预测值y_hat
#
#     # 反向传播
#     def backward(self, y, activate):
#         # 求导
#         self.delta = activate(self.z, True) + SquareErrorSum(self.y_hat, y, True)
#         # 对W 进行求导
#         dW = np.dot(self.delta, self.X.T)
#         b = self.delta
#         # 更新权重参数 W ,b
#         self.W -= self.learningrate * dW
#         self.b -= self.learningrate * b
#
#     def setLearningrate(self,l):
#         self.learningrate = l
#
# model = model()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值