tensorflow2.0(一)----多层感知机(MLP)

在TensorFlow 1.X版本中,调用tf.enable_eager_execution()函数启动Eager Execution模式。则需要调用tf.compat.v1.disable_eager_execution()函数)张量流使用张量(张量)作为数据的基本单元。

自动求导机制
对y = x*x的导数

import tensorflow as tf
x = tf.Variable(initial_value=3.)
with tf.GradientTape() as tape: # 在 tf.GradientTape() 的上下文内,所有计算步骤都会被记录以用于求导
	y = tf.square(x)
y_grad = tape.gradient(y, x) # 计算y关于x的导数
print([y, y_grad])

x 是一个初始化为3的 变量 (Variable),使用 tf.Variable() 声明。与普通张量一样,变量同样具有形状、类型和值三种属性。使用变量需要有一个初始化过程,可以通过在tf.Variable() 中指定initial_value 参数来指定初始值。变量与普通张量的一个重要区别是其默认能够被TensorFlow的自动求导机制所求导,因此往往被用于定义机器学习模型的参数。tf.GradientTape() 是一个自动求导的记录器,在其中的变量和计算步骤都会被自动记录。在上面的示例中,变量 x 和计算步骤 y = tf.square(x) 被自动记录,因此可以通过 y_grad =tape.gradient(y, x) 求张量 y 对变量 x 的导数。在机器学习中,更加常见的是对多元函数求偏导数,以及对向量或矩阵的求导。以下代码是如何使用 tf.GradientTape() 计算函数的偏导数。

x = tf.constant([[1., 2.], [3., 4.]])
y = tf.constant([[1.], [2.]])
w = tf.Variable(initial_value=[[1.], [2.]])
b = tf.Variable(initial_value=1.)
with tf.GradientTape() as tape:
	L = 0.5 * tf.reduce_sum(tf.square(tf.matmul(x, w) + b - y))
w_grad, b_grad = tape.gradient(L, [w, b]) # 计算L(w, b)关于w, b的偏导数
print([L.numpy(),w_grad.numpy(),b_grad.numpy])

numpy下线性回归:

a, b = 0, 0
num_epoch = 10000
learning_rate = 1e-3
for e in range(num_epoch):
# 手动计算损失函数关于自变量(模型参数)的梯度
y_pred = a * X + b
grad_a, grad_b = (y_pred - y).dot(X), (y_pred - y).sum()
# 更新参数
a, b = a - learning_rate * grad_a, b - learning_rate * grad_b
print(a, b)

tensorflow下的线性回归

import tensorflow as tf
x = tf.constant(x)
y = tf.constant(y)

a = tf.Variable(initial_value=0.)
b = tf.Variable(initial_value=0.)
variables = [a,b]

num_epoch = 10000
optimizer = tf.keras.optimizers.SGD(learning_rate = 0.0003)
for e in range(num_epoch):
	# 使用tf.GradientTape()记录损失函数的梯度
	with tf.GradientTape() as tape:
		y_pred = a * x + b
		loss = 0.5 * tf.reduce_sum(tf.square(y_pred - y)) # 损失函数
	grads = tape.gradient(loss, variables) # 求偏导
	optimizer.apply_gradients(grads_and_vars = zip(grads, variables)) # 优化器
print(a, b)

使用tf.keras.optimizers.SGD(learning_rate=1e-3) 声明了一个梯度下降 优化器 (Optimizer)。优化器可以帮助我们根据计算出的求导结果更新模型参数,从而最小化某个特定的损失函数,具体使用方式是调用其 apply_gradients() 方法。 optimizer.apply_gradients() 需要提供参数 grads_and_vars ,即待更新的变量(如上述代码中的 variables )及损失函数关于这些变量的偏导数(如上述代码中的grads )。这里需要传入一个Python列表(List),列表中的每个元素是一个 (变量的偏导数,变量)对。比如这里是 [(grad_a, a), (grad_b, b)] 。我们通过 grads = tape.gradient(loss,variables) 求出tape中记录的 loss 关于 variables = [a, b] 中每个变量的偏导数,也就是grads = [grad_a, grad_b] ,再使用Python的 zip() 函数将 grads = [grad_a, grad_b] 和variables = [a, b] 拼装在一起,就可以组合出所需的参数了。

自定义模型类

在实际中使用实例化的模型类model = Modle 代替y = a * x +b ,然后使用y_pred = model(x)调用模型,并使用model.variables获取模型参数

tensorflow模型建立和训练,模型(model)和层(layer)

'''
模型类
'''
class MyModel(tf.keras.Model):
	def __init__(self):
		super().__init__()   # python2中 super(MyModel,self).__init__()
		# 此处添加初始代码(包含call方法中会用到的层),例如
		# layer1 = tf.keras.layers.BuiltInLayer(...)
		# layer2 = MyCustomLayer()

	def call(self,input):
		# 此处添加模型调用的代码(处理输入并返回输出),例如
		# x = layer1(input)
		# output = layer2(x)

	# 还可以添加自定义的函数
		

将上面线性模型y_pred = a * x + b ,以模型类的方式编写:

import tensorflow as tf

x = tf.constant([[1.0,2.0,3.0],[4.0,5.0,6.0]])
y = tf.constant([[10.0],[20.0]])

class Linear(tf.keras.Model):
	def __init__(self):
		super().__init__()
		self.dense = tf.keras.layer.Dence(
			units = 1,
			activation=None,
			kernel_initializer=tf.zeors_initializer(),
			bias_initializer=tf.zeros_initializer(),
		)
	def call(self,input):
		output = self.dense(input)

		return output = 

model = Linear()
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
for i in range(100):
	with tf.GradieneTape() as tape:
		y_pred = model(x)    # 全连接层(不激活时)相当于线性变换
		loss = tf.reduce_mean(tf.square(y_pred - y))
	grads = tape.gradient(loss,model.variables) # model.variables获取模型中的所有变量
	optimizer.apply_gradients(grads_and_vars=zip(grads,model.variables))
print(model.variables)

多层感知机(MLP),进行一下步骤:
1、使用 tf.keras,datasets 获取数据集并预处理
2、使用 tf.keras.Model 和 tf.keras.layers 构建模型
3、构建模型训练流程,使用 tf.keras.losses 进行损失函数的计算,并使用 tf.keras.optimizer 优化模型
4、构建模型评估流程,使用 tf.keras.metrics计算评估指标

import tensorflow as tf 

'''
加载数据
'''

class MNISTLoader():
	def __init__(self):
		mnist = tf.keras.datasets.mnist # 自动从网上加载数据
		(self.train_data,self.train_label),(self.test_train,self.test_label) = mnist.load_data()
		# MNIST中的图像默认为unit8(0-255)。下面将其归一化,并在最后加一维作为颜色通道
		self.train_data = np.expand_dims(self.train_data.astype(np.float32) / 255.0,axis = -1)
		# [60000,28,28,1],np.expand_dims()添加一维通道
		self.test_data = np.expand_dims(self.test_data.astype(np.float32) / 255.0,axis = -1)
		# [10000,28,28,1]
		self.train_label = self.train_label.astype(np.int32) 
		self.test_label = self.test_label.astype(np.int32)
		self.num_train_data,self_num_test_data = self.train_data.shape[0],self.test_data.shape[0]
	
	def get_batch(self,batch_size):
		# 从数据中随机取出batch_size个元素并返回
		index = np.random.randint(0,np.shape(self.train_data)[0],batch_size)
		return self.train_data[index,:],self.train_label[index]

'''
模型构建:tf.keras.Model 和 tf.keras.Layer
'''
class MLP(tf.keras.Model):
	def __init__(self):
		super().__init__:
		self.flatten = tf.keras.layers.Flatten() # 将除第一维(batch_size以外的维度展平
		self.dense1 = tf.keras.layers.Dense(units=100,activation=tf.nn.relu)
		self.dense2 = tf.keras.layers.Dense(units=10)
	
	def call(self,inputs):            # [batch_size,28,28,1]
		x = self.flatten(inputs)      # [batch_size,784]
		x = self.dense1(x)            # [batch_size,100]
		x = self.dense2(x)            # [batch_size,10]
		output = tf.nn.softmax(x)

'''
模型训练:tf.keras.losses 和 tf.keras.optimizer
'''
num_epochs = 5
batch_size = 50
learning_rate = 0.001
model = MLP()
data_loader = MNISTLoader()
optimizer = tf.keras.optimizers.Adam(learning_rate)

num_batches = int(data_loader.num_train_data // batch_size * num_epochs)
for batch_index in range(num_batches):
	x,y = data_loader.get_batch(batch_size)
	with tf.GradieneTape() as tape:
		y_pred = model(x)
		loss = tf.keras.losses.sparse_categorical_crossentropy(y_true=y,y_pred=y_pred)
		print("batch &d:loss %f" % (batch_index.loss.numpy()))
	grads = tape.gradient(loss,model.variables)
	optimizer.apply_gradients(grads_and_vars=zip(grads,model.variables))

'''
模型评估:tf.keras.metrics
'''
sparse_categorical_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()
num_batches = int(data_losder.num_test_data // batch_size)
for batch_index in range(num_batches):
	start_index,end_index = batch_index *batch_size,(batch_index + 1* batch_size 
	y_pred = model.predict(data_loader.test_data [START_INDEX:END_INDEX])
	sparse_categorical_accuracy.update_state(y_ture = data_loader.test_label[start_index:
	end_index],y_pred=y_pred)
	print("test accuracy: %f" % sparse_categorical_accuracy.result())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值