ZBH4444 2021-03-12 00:07 采纳率: 100%

# tensorflow2.x 深度学习 使用相同梯度进行梯度下降的两个相同神经网络，得到的结果却不同

``````for step, (x, y) in enumerate(train_db):
with tf.GradientTape() as tape:  # 构建梯度记录环境
# 插入通道维度，=>[b,32,32,1]
intermediate_out = conv_net(x, training=True)
intermediate_out = tf.reshape(intermediate_out, [-1, 512])
out = fc_net(intermediate_out, training=True)

# 真实标签 one-hot 编码，[b] => [b, 10]
y_one_hot = tf.one_hot(y, depth=10)
# 计算交叉熵损失函数，标量
loss = tf.losses.categorical_crossentropy(y_one_hot, out, from_logits=True)
loss = tf.reduce_mean(loss)

# 列表合并，合并 2 个子网络的参数
variables = conv_net.trainable_variables + fc_net.trainable_variables
# 对所有参数求梯度

``````# 加载刚刚保存的相同的VGG-13网络，利用刚刚生成的grad进行梯度下降
# 训练前测试一下模型准确率
t_accuracy_before = run_test(t_conv_net, t_fc_net, test_db)
print("t_accuracy before train = ", t_accuracy_before)

t_variables = t_conv_net.trainable_variables + t_fc_net.trainable_variables

``````import os
import numpy as np
import math
import tensorflow as tf  # 导入 TF 库
from tensorflow.keras import layers, Sequential, losses, optimizers, datasets, models
import matplotlib.pyplot as plt

# 设置 GPU 显存使用方式为：为增长式占用-----------------------
gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
try:  # 设置 GPU 为增长式占用
for gpu in gpus:
tf.config.experimental.set_memory_growth(gpu, True)
except RuntimeError as e:
# 打印异常
print(e)

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
tf.random.set_seed(2345)

def vgg13():
conv_layers = [
# 先创建包含多网络层的列表
# Conv-Conv-Pooling 单元 1
# 64 个 3x3 卷积核, 输入输出同大小
# 高宽减半

# Conv-Conv-Pooling 单元 2,输出通道提升至 128，高宽大小减半

# Conv-Conv-Pooling 单元 3,输出通道提升至 256，高宽大小减半

# Conv-Conv-Pooling 单元 4,输出通道提升至 512，高宽大小减半

# Conv-Conv-Pooling 单元 5,输出通道提升至 512，高宽大小减半
]

# 利用前面创建的层列表构建网络容器
conv_net = Sequential(conv_layers)

# 创建 3 层全连接层子网络
fc_net = Sequential([
layers.Dense(256, activation=tf.nn.relu),
layers.Dense(128, activation=tf.nn.relu),
layers.Dense(10, activation=None),
])

# build2 个子网络，并打印网络参数信息
conv_net.build(input_shape=[None, 32, 32, 3])
fc_net.build(input_shape=[None, 512])

return conv_net, fc_net

def preprocess(x, y):
x = tf.cast(x, dtype=tf.float32) / 255.
y = tf.cast(y, dtype=tf.int32)  # 类型转换
return x, y

def generating_data_set(input_x, input_y, batch):
# 构建训练集对象，随机打乱，预处理，批量化
db = tf.data.Dataset.from_tensor_slices((input_x, input_y))
db = db.shuffle(1000).map(preprocess).batch(batch)  # 构建测试集对象，预处理，批量化
return db

def run_test(conv_net, fc_net, test_db):
# 记录预测正确的数量，总样本数量
correct_num, total_num = 0, 0
for x, y in test_db:  # 遍历所有训练集样本
# 插入通道维度，=>[b,28,28,1]
intermediate_out = conv_net(x, training=False)
intermediate_out = tf.reshape(intermediate_out, [-1, 512])
out = fc_net(intermediate_out, training=False)
# 先经过 softmax，再 argmax
prob = tf.nn.softmax(out, axis=1)
pred = tf.argmax(prob, axis=1)
pred = tf.cast(pred, dtype=tf.int32)

correct = tf.cast(tf.equal(pred, y), dtype=tf.int32)
correct = tf.reduce_sum(correct)
total_num += x.shape[0]
correct_num += int(correct)

# 计算准确率
accuracy = correct_num / total_num
return accuracy

(x, y), (x_test, y_test) = datasets.cifar10.load_data()  # 数据集为cifar10
# 删除 y 的一个维度，[b,1] => [b]
y = tf.squeeze(y, axis=1)
y_test = tf.squeeze(y_test, axis=1)

train_db = generating_data_set(x, y, 128)
test_db = generating_data_set(x_test, y_test, 64)

conv_net, fc_net = vgg13()  # 使用的神经网络为VGG-13

# 将神经网络保存
conv_net.save('conv_net0.h5')
fc_net.save('fc_net0.h5')
print("第一个模型：")
# 训练前测试一下模型准确率
accuracy_before = run_test(conv_net, fc_net, test_db)
print("accuracy before train = ", accuracy_before)

for step, (x, y) in enumerate(train_db):
with tf.GradientTape() as tape:  # 构建梯度记录环境
# 插入通道维度，=>[b,32,32,1]
intermediate_out = conv_net(x, training=True)
intermediate_out = tf.reshape(intermediate_out, [-1, 512])
out = fc_net(intermediate_out, training=True)

# 真实标签 one-hot 编码，[b] => [b, 10]
y_one_hot = tf.one_hot(y, depth=10)
# 计算交叉熵损失函数，标量
loss = tf.losses.categorical_crossentropy(y_one_hot, out, from_logits=True)
loss = tf.reduce_mean(loss)

# 列表合并，合并 2 个子网络的参数
variables = conv_net.trainable_variables + fc_net.trainable_variables
# 对所有参数求梯度

# 训练后测试一下模型准确率
accuracy_after = run_test(conv_net, fc_net, test_db)
print("accuracy after train = ", accuracy_after)

del conv_net
del fc_net

print("\n第二个模型：")
# 训练前测试一下模型准确率
t_accuracy_before = run_test(t_conv_net, t_fc_net, test_db)
print("t_accuracy before train = ", t_accuracy_before)

t_variables = t_conv_net.trainable_variables + t_fc_net.trainable_variables

# 训练后测试一下模型准确率
t_accuracy_after = run_test(t_conv_net, t_fc_net, test_db)
print("t_accuracy after train = ", t_accuracy_after)
``````
• 写回答

#### 2条回答默认 最新

• 深白色的风 2021-03-15 13:58
关注

在上面给的代码的第164行处插入

``optimizer = optimizers.Adam(lr=1e-4)``

重新初始化optimizer，这样两个模型训练后的测试结果就一样了，望采纳

本回答被题主选为最佳回答 , 对您是否有帮助呢?
评论

#### 悬赏问题

• ¥15 苹果系统的mac m1芯片的笔记本使用ce修改器使用不了
• ¥15 单相逆变的电压电流双闭环中进行低通滤波PID算法改进
• ¥15 关于#java#的问题，请各位专家解答！
• ¥15 如何卸载arcgis 10.1 data reviewer for desktop
• ¥15 共享文件夹会话中为什么会有WORKGROUP
• ¥15 关于#python#的问题：使用ATL02数据解算光子脚点的坐标(操作系统-windows)
• ¥115 关于#python#的问题：未加密前两个软件都可以打开，加密后只有A软件可打开，B软件可以打开但读取不了数据
• ¥15 在matlab中Application Compiler后的软件无法打开
• ¥15 想问一下STM32创建工程模板时遇到得问题
• ¥15 Fiddler抓包443