【深度学习】3:多层感知器MLP实现MNIST数据集手写数字识别

本文使用TensorFlow框架搭建了一个含一层隐藏层的BP神经网络,用于识别MNIST手写数字数据集,并详细介绍了网络搭建过程及训练步骤。
部署运行你感兴趣的模型镜像

2024年内容:新的实现方式

使用多层感知器(MLP)来实现一个简单的BP神经网络,通过反向传播算法(BP算法)来调整权重。MNIST数据集包含手写数字图像(28x28像素的灰度图像),我们将它们展开成784维的向量来输入到神经网络中。

import numpy as np
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import SGD

# 加载 MNIST 数据集
(X_train, y_train), (X_test, y_test) = mnist.load_data()

# 预处理数据
X_train = X_train.reshape(-1, 28 * 28).astype("float32") / 255  # 展开为784维向量并归一化
X_test = X_test.reshape(-1, 28 * 28).astype("float32") / 255    # 展开为784维向量并归一化
y_train = to_categorical(y_train, 10)  # 将标签转为one-hot编码
y_test = to_categorical(y_test, 10)

# 构建 BP 神经网络模型
model = Sequential()
model.add(Dense(128, input_shape=(784,), activation="sigmoid"))  # 隐藏层 1,128 个节点
model.add(Dense(64, activation="sigmoid"))                       # 隐藏层 2,64 个节点
model.add(Dense(10, activation="softmax"))                       # 输出层,10 个节点对应 10 个数字类别

# 编译模型
model.compile(optimizer=SGD(learning_rate=0.1),  # 使用随机梯度下降优化器
              loss="categorical_crossentropy",   # 损失函数
              metrics=["accuracy"])

# 训练模型
model.fit(X_train, y_train, epochs=20, batch_size=32, validation_data=(X_test, y_test))

# 评估模型
test_loss, test_accuracy = model.evaluate(X_test, y_test)
print(f"Test accuracy: {test_accuracy * 100:.2f}%")

代码解释:

数据加载和预处理:

  • 使用 mnist.load_data() 来加载MNIST数据集,包含6万张训练图片和1万张测试图片。
  • 将28x28的图像数据展开成784维向量,并归一化到[0, 1]范围。
  • 将标签转换为one-hot编码格式,以便于使用交叉熵损失函数。

模型构建:

  • 使用 Sequential 模型构建一个多层感知器。
  • 第一层为隐藏层,包含128个神经元,使用 sigmoid 激活函数。
  • 第二层为隐藏层,包含64个神经元,同样使用 sigmoid 激活函数。
  • 最后一层为输出层,包含10个神经元,对应数字0到9,使用 softmax 激活函数,以生成10类概率分布。

模型编译和训练:

  • 编译模型,设置优化器为随机梯度下降(SGD),学习率为0.1,损失函数为 categorical_crossentropy。
  • 使用 model.fit 进行模型训练,20个周期,每批次32个样本,自动使用训练集和测试集验证模型效果。

模型评估:

  • 使用 model.evaluate 在测试集上评估模型,并输出最终准确率。

这个模型在20个训练周期后,通常能在测试集上达到90%左右的识别准确率。





2018年内容:用TensorFlow写的

1 、加载MNIST数据集

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

mnist是一个轻量级的类。它以Numpy数组的形式存储着训练、校验和测试数据集,也是Google做图片识别的经典数据集。

2、运行TensorFlow框架

import tensorflow as tf

sess = tf.InteractiveSession()
init = tf.global_variables_initializer()
sess.run(init)

TensorFlow框架与后端的连接叫做session,也就是说我们用session启动TensorFlow框架(详情就要自己深入了解了)

3、预定义输入值X,真实值Y

X = tf.placeholder(tf.float32, shape=[None, 784])
Y = tf.placeholder(tf.float32, shape=[None, 10])
  • X,Y现由占位符表示,可以在TensorFlow运行某一计算时,根据该占位符输入的具体的值而进行计算;
  • tf.float32 是存储的类型;shape=[None, 784]是数据维度大小——因为MNIST数据集中每一张图片大小都是2828的,计算时候是将2828的二维数据转换成一个一维的、长度为784的新向量。None表示其值大小不定,意即选中的X、Y的数量暂时不定

4、创建BP神经网络

"""
用随机数列生成的方式,创建含一个隐藏层的神经网络。(784,300,10)
"""
#truncated_normal:选取位于正态分布均值=0.1附近的随机值
w1 = tf.Variable(tf.truncated_normal([784,300],stddev=0.1))
w2 = tf.Variable(tf.zeros([300,10]))
b1 = tf.Variable(tf.zeros([300]))
b2 = tf.Variable(tf.zeros([10]))
#relu、softmax都为激活函数
L1 = tf.nn.relu(tf.matmul(X,w1)+b1)
y = tf.nn.softmax(tf.matmul(L1,w2)+b2)

BP神经网络输入层有784个神经元、隐藏层300个神经元、输出层10个神经元。初始化各级权重w1、w2;各级偏置值b1、b2——都是采用随机数列生成的方式。定义隐藏层、输出层的计算方式以及各自的激活函数。

5、计算误差并用梯度下降法优化权重

#二次代价函数:计算预测值y与真实值Y之间的误差
loss = tf.reduce_mean(tf.square(Y - y))
#梯度下降法:选用GradientDescentOptimizer优化器,学习率为0.5
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(loss)

误差也叫损失函数、代价函数。TensorFlow中有大量内置的优化算法,这里我们选用最简单的GradientDescentOptimizer优化器让交叉熵下降,步长为定为0.5

6、计算准确率

#结果存放在一个布尔型列表中
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(Y,1))
#求准确率
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
  • tf.argmax()函数:是返回对象在某一维上的其数据最大值所对应的索引值,由于这里的标签向量都是由0,1组成,因此最大值1所在的索引位置就是对应的类别标签
  • tf.argmax(y,1)返回的是对于任一输入x预测到的标签值,tf.argmax(Y,1)代表正确的标签值
  • correct_prediction 这里是返回一个布尔数组。为了计算我们分类的准确率,我们将布尔值转换为浮点数来代表对与错,然后取平均值。例如:[True, False, True, True]变为[1,0,1,1],计算出准确率就为0.75

7、其他说明

batch_xs,batch_ys = mnist.train.next_batch(batch_size)
		sess.run(train_step,feed_dict=({X:batch_xs,Y:batch_ys}))
		acc = sess.run(accuracy,feed_dict={X:mnist.test.images,Y:mnist.test.labels})
  • batch_xs与batch_ys:是从MNIST数据集中按批次数取得的:数据项与标签项
  • feed_dict=({X:batch_xs,Y:batch_ys}语句:是将batch_xs、batch_ys代表的值传入X、Y

8、源码与效果展示

# -*- coding:utf-8 -*-
# -*- author:zzZ_CMing
# -*- 2018/01/23;21:49
# -*- python3.5

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

#读取MNIST数据集
mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
#设置每个批次的大小
batch_size = 500
#计算一共有多少个批次(地板除)
n_batch = mnist.train.num_examples//batch_size
#预定义输入值X、输出真实值Y    placeholder为占位符
X = tf.placeholder(tf.float32,[None,784])
Y = tf.placeholder(tf.float32,[None,10])



"""
用随机数列生成的方式,创建含一个隐藏层的神经网络。(784,300,10)
"""
#truncated_normal:选取位于正态分布均值=0.1附近的随机值
w1 = tf.Variable(tf.truncated_normal([784,300],stddev=0.1))
w2 = tf.Variable(tf.zeros([300,10]))
b1 = tf.Variable(tf.zeros([300]))
b2 = tf.Variable(tf.zeros([10]))
#relu、softmax都为激活函数
L1 = tf.nn.relu(tf.matmul(X,w1)+b1)
y = tf.nn.softmax(tf.matmul(L1,w2)+b2)
#二次代价函数:预测值与真实值的误差
loss = tf.reduce_mean(tf.square(Y - y))
#梯度下降法:选用GradientDescentOptimizer优化器,学习率为0.5
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(loss)
#结果存放在一个布尔型列表中
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(Y,1))
#求准确率
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))


#初始化变量,激活tf框架
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

for i in range(21):
	for batch in range(n_batch):
		batch_xs,batch_ys = mnist.train.next_batch(batch_size)
		sess.run(train_step,feed_dict=({X:batch_xs,Y:batch_ys}))
		acc = sess.run(accuracy,feed_dict={X:mnist.test.images,Y:mnist.test.labels})
	print("Iter " + str(i)+",Testing Accuracy "+str(acc))

效果展示:
这里写图片描述

迭代10次的准确率就已经到90.85%

您可能感兴趣的与本文相关的镜像

TensorFlow-v2.15

TensorFlow-v2.15

TensorFlow

TensorFlow 是由Google Brain 团队开发的开源机器学习框架,广泛应用于深度学习研究和生产环境。 它提供了一个灵活的平台,用于构建和训练各种机器学习模型

要使用Python实现一个三层感知器神经网络(Perceptron)进行非线性分类,我们需要首先定义网络结构、激活函数、损失函数以及梯度下降优化算法。这里我将为您演示一个基础版本的实现,假设我们有一个简单的二分类问题,比如预测学生是否及格(大于等于60分为及格,否则不及格)。我们将采用Sigmoid激活函数。 ```python import numpy as np class PerceptronNeuron: def __init__(self, weights, bias): self.weights = weights self.bias = bias def sigmoid(self, x): return 1 / (1 + np.exp(-x)) def forward_pass(self, input_data): linear_combination = np.dot(input_data, self.weights) + self.bias activation = self.sigmoid(linear_combination) return activation class PerceptronNetwork: def __init__(self, num_inputs, hidden_units=5, output_units=1): # Initialize random weights and biases for neurons self.hidden_layer = [PerceptronNeuron(np.random.randn(num_inputs + 1), np.random.randn(1)) for _ in range(hidden_units)] self.output_layer = PerceptronNeuron(np.random.randn(hidden_units + 1), np.random.randn(1)) def forward_pass(self, input_data): hidden_outputs = [neuron.forward_pass(input_data) for neuron in self.hidden_layer] final_output = self.output_layer.forward_pass(np.concatenate((hidden_outputs, np.ones((1, len(hidden_outputs)))))) return final_output def train_network(network, training_data, labels, learning_rate=0.01, epochs=1000): for epoch in range(epochs): for i in range(len(training_data)): prediction = network.forward_pass(training_data[i]) if prediction < 0.5 and labels[i] == 1 or prediction >= 0.5 and labels[i] == 0: error = labels[i] - prediction delta_hidden = error * prediction * (1 - prediction) delta_output = error # Update weights and biases network.hidden_layer[0].weights += learning_rate * np.dot(training_data[i], delta_hidden) network.hidden_layer[0].bias += learning_rate * delta_hidden for j in range(1, len(network.hidden_layer)): network.hidden_layer[j].weights += learning_rate * np.dot(hidden_outputs[i][j-1], delta_hidden) network.hidden_layer[j].bias += learning_rate * delta_hidden network.output_layer.weights += learning_rate * np.dot(np.append(hidden_outputs[i], np.array([1])), delta_output) network.output_layer.bias += learning_rate * delta_output # 假设我们有如下数据和标签 training_data = np.array([[80, 90, 70], [75, 80, 60], [95, 92, 85]]) labels = np.array([1, 0, 1]) # 及格为1,不及格为0 network = PerceptronNetwork(len(training_data[0]), 3) # 三层网络,第一层3个隐藏单元 train_network(network, training_data, labels) # 使用训练好的模型对新数据进行预测 new_student = np.array([85, 88, 78]) prediction = network.forward_pass(new_student) if prediction >= 0.5: print("学生及格") else: print("学生不及格")
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月涌大江流丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值