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，这样两个模型训练后的测试结果就一样了，望采纳

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

#### 悬赏问题

• ¥33 集成BiLSTM模型和GCN模型时，前模型的输出不匹配后模型的输入
• ¥15 关于液体厚度提取，和铺展轨迹数据化处理
• ¥20 对方微信是wxid如何添加成好友？或者转换成微信号？
• ¥15 yolov5实验数据好，但是自己拍摄的照片检测结果差
• ¥15 做过dali2.0认证的技术，
• ¥15 一道python难题
• ¥15 matlab 免疫算法
• ¥50 可视化界面构建，实现信息模块功能
• ¥15 基于bert-base-chinese的中文文本处理
• ¥15 高价求抖音抓包技术，抖音抓包无网络问题