前向传播实战:分类问题手写训练参数,损失函数为MSE

“”“前向传播实战:分类问题手写训练参数,损失函数为MSE”""

"""前向传播实战:分类问题手写训练参数,损失函数为MSE"""
import matplotlib
from keras import metrics
from matplotlib import pyplot as plt
import tensorflow as tf
# from tensorflow import keras
from tensorflow.keras import datasets
import os

# 图的默认参数
matplotlib.rcParams['font.size'] = 20   # 设置字体大小
matplotlib.rcParams['figure.titlesize'] = 20    # s设置图片标题大小
matplotlib.rcParams['figure.figsize'] = [9, 7]  # 设置图片大小
matplotlib.rcParams['font.family'] = ['STKaiTi']  # 设置字体样式
matplotlib.rcParams['axes.unicode_minus'] = False   # 字符显示


# 调整输出信息,只输出error
os.environ['TF_CFF_MIN_LOG_LEVEL'] = '2'
# 设置log输出信息的,也就是程序运行时系统打印的信息。

# x:[60k, 28,28]
# y:[60k]
(x, y), _ = datasets.mnist.load_data()
# x[0-255]-1
x = tf.convert_to_tensor(x, dtype=tf.float32)/255
y = tf.convert_to_tensor(y, dtype=tf.int32)
print(x.shape, y.shape, x.dtype, y.dtype)
print(tf.reduce_min(x), tf.reduce_max(x))
print(tf.reduce_min(y), tf.reduce_max(y))

# 设置一批数据为128
train_db = tf.data.Dataset.from_tensor_slices((x, y)).batch(128)
# 把给定的元组、列表和张量等数据进行特征切片。切片的范围是从最外层维度开始的。
# <BatchDataset shapes: ((None, 28, 28), (None,)), types: (tf.float32, tf.int32)>
train_iter = iter(train_db)
print(train_iter)
sample = next(train_iter)
# 我们首先要知道什么是可迭代的对象(可以用for循环的对象)Iterable:
# 一类:list,tuple,dict,set,str
# # 二类:generator,包含生成器和带yield的generatoe function
# 而生成器不但可以作用于for,还可以被next()函数不断调用并返回下一个值,可以被next()函数不断返回下一个值的对象称为迭代器:Iterator
# 生成器都是Iterator对象,但list,dict,str是Iterable,但不是Iterator,要把list,dict,str等Iterable转换为Iterator可以使用iter()函数
print('batch:', sample[0].shape, sample[1].shape)

# 定义参数和学习率
# 第一层的参数
w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1))
b1 = tf.Variable(tf.zeros(256))
# 第二层参数
w2 = tf.Variable(tf.random.truncated_normal([256, 128], stddev=0.1))
b2 = tf.Variable(tf.zeros(128))
# 第三层参数
w3 = tf.Variable(tf.random.truncated_normal([128, 10], stddev=0.1))
b3 = tf.Variable(tf.zeros(10))

lr = (1e-1)*8.5
losses = []
acces = []
acc_meter = metrics.SparseCategoricalAccuracy()

for epoch in range(10):
    # 分批循环数据集
    for step, (x, y) in enumerate(train_db):
        # 把X转换为[batch,784]
        x = tf.reshape(x, [-1, 28*28])
        # tensor提供的自动求导
        with tf.GradientTape() as tape:
            # x[128,784]->[128,256]
            h1 = x@w1+tf.broadcast_to(b1, [x.shape[0], 256])
            # 非线性激励
            h1 = tf.nn.relu(h1)
            # x[128,256]->[128,128]
            h2 = h1@w2+b2
            h2 = tf.nn.relu(h2)
            # 输出[128,10]
            out = h2@w3+b3
            # 对y进行one_hot转变为[128,10]
            y_onehot = tf.one_hot(y, depth=10)
            # 损失函数:(y-y')**2/128
            loss = tf.square(y_onehot-out)
            loss = tf.reduce_mean(loss)
        # 传入损失函数,参数
        grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3])
        # 更新参数
        w1.assign_sub(lr*grads[0])
        b1.assign_sub(lr*grads[1])
        w2.assign_sub(lr*grads[2])
        b2.assign_sub(lr*grads[3])
        w3.assign_sub(lr*grads[4])
        b3.assign_sub(lr*grads[5])

        acc_meter.update_state(y, out)
        # 输出损失值
        if step % 100 == 0:
            print(epoch, step, 'loss', float(loss), 'acc', acc_meter.result().numpy())
            losses.append(float(loss))
            acces.append(acc_meter.result().numpy())
print(losses)
print(acces)
plt.figure()
plt.plot(losses, color='C0', marker='s', label='训练')
plt.plot(acces, color='green', marker='s', label='训练')
plt.xlabel('epoch')
plt.ylabel('MSE,ACC')
plt.show()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值