如题,在M1 Mac上使用tensorflow跑vgg网络,正常时准确率不断上升,经过5个epoch后为0.7315,但是速度很慢。在安装了tensorflow-metal进行硬件加速后,时间大幅缩短,但是准确率一直维持在0.1左右,几乎与乱选准确率相同。
代码为北大tensorflow笔记公开课CNN部分,数据集为cifar10,具体代码如下:
import tensorflow as tf
import os
import numpy as np
from matplotlib import pyplot as plt
from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense
from tensorflow.keras import Model
np.set_printoptions(threshold=np.inf)
cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
class VGG16(Model):
def __init__(self):
super(VGG16, self).__init__()
self.c1 = Conv2D(filters=64, kernel_size=(3, 3), padding='same') # 卷积层1
self.b1 = BatchNormalization() # BN层1
self.a1 = Activation('relu') # 激活层1
self.c2 = Conv2D(filters=64, kernel_size=(3, 3), padding='same', )
self.b2 = BatchNormalization() # BN层1
self.a2 = Activation('relu') # 激活层1
self.p1 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')
self.d1 = Dropout(0.2) # dropout层
self.c3 = Conv2D(filters=128, kernel_size=(3, 3), padding='same')
self.b3 = BatchNormalization() # BN层1
self.a3 = Activation('relu') # 激活层1
self.c4 = Conv2D(filters=128, kernel_size=(3, 3), padding='same')
self.b4 = BatchNormalization() # BN层1
self.a4 = Activation('relu') # 激活层1
self.p2 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')
self.d2 = Dropout(0.2) # dropout层
self.c5 = Conv2D(filters=256, kernel_size=(3, 3), padding='same')
self.b5 = BatchNormalization() # BN层1
self.a5 = Activation('relu') # 激活层1
self.c6 = Conv2D(filters=256, kernel_size=(3, 3), padding='same')
self.b6 = BatchNormalization() # BN层1
self.a6 = Activation('relu') # 激活层1
self.c7 = Conv2D(filters=256, kernel_size=(3, 3), padding='same')
self.b7 = BatchNormalization()
self.a7 = Activation('relu')
self.p3 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')
self.d3 = Dropout(0.2)
self.c8 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')
self.b8 = BatchNormalization() # BN层1
self.a8 = Activation('relu') # 激活层1
self.c9 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')
self.b9 = BatchNormalization() # BN层1
self.a9 = Activation('relu') # 激活层1
self.c10 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')
self.b10 = BatchNormalization()
self.a10 = Activation('relu')
self.p4 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')
self.d4 = Dropout(0.2)
self.c11 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')
self.b11 = BatchNormalization() # BN层1
self.a11 = Activation('relu') # 激活层1
self.c12 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')
self.b12 = BatchNormalization() # BN层1
self.a12 = Activation('relu') # 激活层1
self.c13 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')
self.b13 = BatchNormalization()
self.a13 = Activation('relu')
self.p5 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')
self.d5 = Dropout(0.2)
self.flatten = Flatten()
self.f1 = Dense(512, activation='relu')
self.d6 = Dropout(0.2)
self.f2 = Dense(512, activation='relu')
self.d7 = Dropout(0.2)
self.f3 = Dense(10, activation='softmax')
def call(self, x):
x = self.c1(x)
x = self.b1(x)
x = self.a1(x)
x = self.c2(x)
x = self.b2(x)
x = self.a2(x)
x = self.p1(x)
x = self.d1(x)
x = self.c3(x)
x = self.b3(x)
x = self.a3(x)
x = self.c4(x)
x = self.b4(x)
x = self.a4(x)
x = self.p2(x)
x = self.d2(x)
x = self.c5(x)
x = self.b5(x)
x = self.a5(x)
x = self.c6(x)
x = self.b6(x)
x = self.a6(x)
x = self.c7(x)
x = self.b7(x)
x = self.a7(x)
x = self.p3(x)
x = self.d3(x)
x = self.c8(x)
x = self.b8(x)
x = self.a8(x)
x = self.c9(x)
x = self.b9(x)
x = self.a9(x)
x = self.c10(x)
x = self.b10(x)
x = self.a10(x)
x = self.p4(x)
x = self.d4(x)
x = self.c11(x)
x = self.b11(x)
x = self.a11(x)
x = self.c12(x)
x = self.b12(x)
x = self.a12(x)
x = self.c13(x)
x = self.b13(x)
x = self.a13(x)
x = self.p5(x)
x = self.d5(x)
x = self.flatten(x)
x = self.f1(x)
x = self.d6(x)
x = self.f2(x)
x = self.d7(x)
y = self.f3(x)
return y
model = VGG16()
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['sparse_categorical_accuracy'])
checkpoint_save_path = "./checkpoint/VGG16.ckpt"
if os.path.exists(checkpoint_save_path + '.index'):
print('-------------load the model-----------------')
model.load_weights(checkpoint_save_path)
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
save_weights_only=True,
save_best_only=True)
history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1,
callbacks=[cp_callback])
model.summary()
# print(model.trainable_variables)
file = open('./weights.txt', 'w')
for v in model.trainable_variables:
file.write(str(v.name) + '\n')
file.write(str(v.shape) + '\n')
file.write(str(v.numpy()) + '\n')
file.close()
############################################### show ###############################################
# 显示训练集和验证集的acc和loss曲线
acc = history.history['sparse_categorical_accuracy']
val_acc = history.history['val_sparse_categorical_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
plt.subplot(1, 2, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()
确实有一些用户报告在使用Apple M1芯片的Mac上安装TensorFlow Metal后,模型的准确率下降的问题。这可能是由于TensorFlow Metal在当前版本下仍然处于早期阶段,并且可能存在一些尚未解决的问题。
有几个可能的解决方法可以尝试:
使用Rosetta 2模拟器:将TensorFlow回退到Intel架构版本,并通过Rosetta 2模拟器在M1芯片上运行。这可能可以避免性能和准确率下降的问题,但可能会牺牲一些性能。
等待更新版本:TensorFlow和TensorFlow Metal的开发人员正在积极工作,以改进和优化在M1芯片上的性能和兼容性。随着时间的推移,新的更新版本可能会提供更好的准确率和性能。
尝试其他框架:如果您是使用Mac上的深度学习框架,可以尝试使用其他支持M1芯片的框架,例如PyTorch或Apple自家的Core ML框架。这些框架可能在M1芯片上提供更好的性能和准确率。
请记住,M1芯片是相对较新的技术,尽管TensorFlow Metal已经发布,但在其上运行的框架和工具仍然在发展中。随着时间的推移,更多的优化和改进将使得在M1芯片上的机器学习任务更加稳定和可靠。
不知道你这个问题是否已经解决, 如果还没有解决的话:问题原因: 在安装了TensorFlow-Metal后,模型准确率下降到0.1左右的问题可能由两个主要原因引起。
兼容性问题:TensorFlow-Metal是专为苹果M1芯片优化的加速库,但它可能与原始的TensorFlow框架存在兼容性问题,导致性能下降或准确率降低。
加速方法问题:在使用TensorFlow-Metal加速时,可能需要进行一些特殊配置或调整参数,才能获得与原始TensorFlow相当的准确率和性能。
解决方案: 要解决这个问题,可以尝试以下几个步骤:
更新TensorFlow版本: 确保您的TensorFlow版本是最新的。在终端中运行以下命令可以更新TensorFlow:pip install --upgrade tensorflow
检查TensorFlow-Metal的版本: 确保您安装的TensorFlow-Metal版本是最新的。在终端中运行以下命令可以安装或更新TensorFlow-Metal: pip install --upgrade tensorflow-metal
禁用TensorFlow-Metal并重新训练: 如果更新版本后问题仍然存在,您可以尝试禁用TensorFlow-Metal并重新训练模型。只需注释掉或删除代码中与TensorFlow-Metal有关的部分,然后再次运行代码:
python # import tensorflow as tf # tf.config.experimental.set_virtual_device_configuration(tf.config.experimental.list_physical_devices('GPU')[0], # [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
/ 255.0
操作可能会导致数值变化较大,从而影响模型的训练。可以尝试使用更小的缩放值,例如/ 127.5 - 1
,然后重新训练模型。python # 数据预处理 x_train, x_test = x_train / 127.5 - 1, x_test / 127.5 - 1
python # 编译和训练模型 optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001) model.compile(optimizer=optimizer, loss='sparse_categorical_crossentropy', metrics=['accuracy'])
如果上述步骤都不起作用,您可能需要等待TensorFlow-Metal社区或官方发布更新以解决兼容性问题。
请注意,这些步骤仅为解决问题的一般指导,具体解决方案可能因环境和配置而异。如果问题仍然存在,建议查阅TensorFlow-Metal的官方文档、社区或在相关论坛寻求帮助。
在M1 Mac上使用 TensorFlow 运行 VGG 网络时遇到的问题可能是由于使用了 TensorFlow Metal 导致的。尽管 TensorFlow Metal 可以提供硬件加速,但某些模型或操作可能不受支持或存在兼容性问题。
要解决这个问题,可以尝试以下几种方法:
确保安装的 TensorFlow 版本是与 TensorFlow Metal 兼容的最新版本,以获得最佳的硬件加速支持。
尝试运行更简单的模型或示例代码,以确定是特定于 VGG 网络的问题还是 TensorFlow Metal 的整体问题。
如果确认是 TensorFlow Metal 导致的问题,可以尝试使用 TensorFlow 的其他后端(如 TensorFlow CPU 或 TensorFlow GPU)来获得更好的准确率。
查看 TensorFlow Metal 的官方文档和社区支持,以了解是否有已知的问题或解决方案适用于你的情况。
另外,还可以尝试使用其他的深度学习框架来在 M1 Mac 上运行 VGG 网络,如 PyTorch、Apple's Core ML 或使用 Metal Performance Shaders 直接编写代码来实现相同的功能。这些框架可能提供更好的性能和兼容性。
希望以上信息对你有帮助!如有其他问题,请随时提问。