【Keras】多GPU训练和模型保存

2024-08-27 18:18
文章标签 训练 保存 模型 gpu keras

本文主要是介绍【Keras】多GPU训练和模型保存,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

先看完整示例 

import osimport tensorflow as tf
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.applications.inception_v3 import InceptionV3
from keras.applications.mobilenet import MobileNet
from keras import  layers
from keras.models import Model
from keras.optimizers import RMSprop
from keras import backend as K
from keras.applications.vgg16 import VGG16
from keras.models import Sequential
from keras.layers import Conv2D, MaxPool2D, Activation, Dropout, Flatten, Dense
from keras.optimizers import SGD
from keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img
import numpy as np
import keras
from keras.preprocessing.image import ImageDataGenerator
from keras.layers import Conv2D, MaxPool2D, Activation, Dropout, Flatten, Dense, GlobalMaxPooling2D
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense
from keras import initializers
from keras.callbacks import ModelCheckpoint, EarlyStopping
from keras.applications.vgg19 import VGG19
from keras.applications.resnet50 import ResNet50
from keras.applications.mobilenet_v2 import MobileNetV2
from keras.preprocessing.image import ImageDataGeneratorfrom keras.utils import multi_gpu_modeldef training_vis(hist):loss = hist.history['loss']val_loss = hist.history['val_loss']acc = hist.history['acc']val_acc = hist.history['val_acc']# make a figurefig = plt.figure(figsize=(8,4))# subplot lossax1 = fig.add_subplot(121)ax1.plot(loss,label='train_loss')ax1.plot(val_loss,label='val_loss')ax1.set_xlabel('Epochs')ax1.set_ylabel('Loss')ax1.set_title('Loss on Training and Validation Data')ax1.legend()# subplot accax2 = fig.add_subplot(122)ax2.plot(acc,label='train_acc')ax2.plot(val_acc,label='val_acc')ax2.set_xlabel('Epochs')ax2.set_ylabel('Accuracy')ax2.set_title('Accuracy  on Training and Validation Data')ax2.legend()plt.tight_layout()GPU_IDS = '0,1,2,3'
os.environ["CUDA_VISIBLE_DEVICES"] = GPU_IDS
GPU_NUM = len(GPU_IDS.split(','))
train_data_path = r"/root/SMJ/train"
val_data_path = r"/root/SMJ/val"
model_save_path = r"/root/SMJ/checkpoints"
model_name = "resnet50"
clc_num = 2
batch_size = 32
nb_train_samples = 0
nb_validation_samples = 0
for cls_dir in os.listdir(train_data_path):nb_train_samples += len(os.listdir(os.path.join(train_data_path, cls_dir)))
for cls_dir in os.listdir(val_data_path):nb_validation_samples += len(os.listdir(os.path.join(val_data_path, cls_dir)))if GPU_NUM <= 1:print("Training with 1 GPU")pre_trained_model = ResNet50(include_top=False, weights='imagenet', input_shape=(224, 224, 3))x = GlobalMaxPooling2D()(pre_trained_model.output)x = Dense(256, activation='relu')(x)x = Dropout(0.5)(x)x = Dense(clc_num, activation='softmax')(x)model = Model(inputs=pre_trained_model.input, outputs=x)
else:print("Training with {} GPU".format(GPU_NUM))with tf.device("/cpu:0"):pre_trained_model = ResNet50(include_top=False, weights='imagenet', input_shape=(224, 224, 3))x = GlobalMaxPooling2D()(pre_trained_model.output)x = Dense(256, activation='relu')(x)x = Dropout(0.5)(x)x = Dense(clc_num, activation='softmax')(x)model = Model(inputs=pre_trained_model.input, outputs=x)model = multi_gpu_model(model, gpus=4)train_datagen = ImageDataGenerator(rescale = 1/255,         # horizontal_flip = True,# vertical_flip = True,# rotation_range = 359,
)
test_datagen = ImageDataGenerator(rescale = 1/255,       
)train_generator = train_datagen.flow_from_directory(train_data_path,target_size=(224,224),batch_size=batch_size,
)test_generator = test_datagen.flow_from_directory(val_data_path,target_size=(224,224),batch_size=batch_size,
)
sgd = optimizers.SGD(lr=0.0001, decay=1e-6, momentum=0.9, nesterov=True)
#for layer in model.layers[:30]:
#    layer.trainable=False
model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])# class ParallelModelCheckpoint(ModelCheckpoint):
#     def __init__(self,model,filepath, monitor='val_loss', verbose=0,
#                  save_best_only=False, save_weights_only=False,
#                  mode='auto', period=1):
#         self.single_model = model
#         super(ParallelModelCheckpoint,self).__init__(filepath, monitor, verbose,save_best_only, save_weights_only,mode, period)#     def set_model(self, model):
#         super(ParallelModelCheckpoint,self).set_model(self.single_model)# model_checkpoint = ParallelModelCheckpoint(model, filepath=os.path.join(model_save_path, model_name + "-{epoch:02d}_loss-{loss:.4f}_val_loss-{val_loss:.4f}.h5"), monitor='val_loss', verbose=1, save_best_only=True, save_weights_only=True) # 解决多GPU运行下保存模型报错的问题model_checkpoint = ModelCheckpoint(filepath=os.path.join(model_save_path, model_name + "-{epoch:02d}_loss-{loss:.4f}_val_loss-{val_loss:.4f}.h5"),monitor='val_loss',verbose=1,save_best_only=True,save_weights_only=True,mode='auto',period=1)hist=model.fit_generator(train_generator,steps_per_epoch=nb_train_samples//(batch_size*GPU_NUM),epochs=500,validation_data=test_generator,validation_steps=nb_validation_samples//(batch_size*GPU_NUM),callbacks=[model_checkpoint])

multi_gpu_model

keras.utils.multi_gpu_model(model, gpus=None, cpu_merge=True, cpu_relocation=False)

将模型复制到不同的 GPU 上。

具体来说,该功能实现了单机多 GPU 数据并行性。 它的工作原理如下:

  • 将模型的输入分成多个子批次。
  • 在每个子批次上应用模型副本。 每个模型副本都在专用 GPU 上执行。
  • 将结果(在 CPU 上)连接成一个大批量。

例如, 如果你的 batch_size 是 64,且你使用 gpus=2, 那么我们将把输入分为两个 32 个样本的子批次, 在 1 个 GPU 上处理 1 个子批次,然后返回完整批次的 64 个处理过的样本。

这实现了多达 8 个 GPU 的准线性加速。

此功能目前仅适用于 TensorFlow 后端。

参数

  • model: 一个 Keras 模型实例。为了避免OOM错误,该模型可以建立在 CPU 上, 详见下面的使用样例。
  • gpus: 整数 >= 2 或整数列表,创建模型副本的 GPU 数量, 或 GPU ID 的列表。
  • cpu_merge: 一个布尔值,用于标识是否强制合并 CPU 范围内的模型权重。
  • cpu_relocation: 一个布尔值,用来确定是否在 CPU 的范围内创建模型的权重。如果模型没有在任何一个设备范围内定义,您仍然可以通过激活这个选项来拯救它。

返回

一个 Keras Model 实例,它可以像初始 model 参数一样使用,但它将工作负载分布在多个 GPU 上。

例子

例 1 - 训练在 CPU 上合并权重的模型

import tensorflow as tf
from keras.applications import Xception
from keras.utils import multi_gpu_model
import numpy as npnum_samples = 1000
height = 224
width = 224
num_classes = 1000# 实例化基础模型(或者「模版」模型)。
# 我们推荐在 CPU 设备范围内做此操作,
# 这样模型的权重就会存储在 CPU 内存中。
# 否则它们会存储在 GPU 上,而完全被共享。
with tf.device('/cpu:0'):model = Xception(weights=None,input_shape=(height, width, 3),classes=num_classes)# 复制模型到 8 个 GPU 上。
# 这假设你的机器有 8 个可用 GPU。
parallel_model = multi_gpu_model(model, gpus=8)
parallel_model.compile(loss='categorical_crossentropy',optimizer='rmsprop')# 生成虚拟数据
x = np.random.random((num_samples, height, width, 3))
y = np.random.random((num_samples, num_classes))# 这个 `fit` 调用将分布在 8 个 GPU 上。
# 由于 batch size 是 256, 每个 GPU 将处理 32 个样本。
parallel_model.fit(x, y, epochs=20, batch_size=256)# 通过模版模型存储模型(共享相同权重):
model.save('my_model.h5')

例 2 - 训练在 CPU 上利用 cpu_relocation 合并权重的模型

..
# 不需要更改模型定义的设备范围:
model = Xception(weights=None, ..)try:parallel_model = multi_gpu_model(model, cpu_relocation=True)print("Training using multiple GPUs..")
except ValueError:parallel_model = modelprint("Training using single GPU or CPU..")
parallel_model.compile(..)
..

例 3 - 训练在 GPU 上合并权重的模型(建议用于 NV-link)

..
# 不需要更改模型定义的设备范围:
model = Xception(weights=None, ..)try:parallel_model = multi_gpu_model(model, cpu_merge=False)print("Training using multiple GPUs..")
except:parallel_model = modelprint("Training using single GPU or CPU..")parallel_model.compile(..)
..

关于模型保存

要保存多 GPU 模型,请通过模板模型(传递给 multi_gpu_model 的参数)调用 .save(fname) 或 .save_weights(fname) 以进行存储,而不是通过 multi_gpu_model 返回的模型。

意思就是直接使用传入方法keras.utils.multi_gpu_model(model, gpus)中的model即可,而不要使用返回的parallel_model,即:

model.save('xxx.h5')

Modelcheckpoint callback 报错 

Modelchecpoint callback函数无法调用也是因为保存时调用的是paralleled_model.save()导致的。 
解决方法一:在modelcheckpoint里参数加上save_weights_only=True后,只会保存模型权重,但是保存的模型只能在同样数量的GPU上载入,而没办法再单GPU下载入。

解决方法二:自定义Callback函数,将callback函数中的paralle model 置为 template model

class ParallelModelCheckpoint(ModelCheckpoint):def __init__(self,model,filepath, monitor='val_loss', verbose=0,save_best_only=False, save_weights_only=False,mode='auto', period=1):self.single_model = modelsuper(ParallelModelCheckpoint,self).__init__(filepath, monitor, verbose,save_best_only, save_weights_only,mode, period)def set_model(self, model):super(ParallelModelCheckpoint,self).set_model(self.single_model)check_point = ParallelModelCheckpoint(single_model ,'best.h5')

载入

这里是使用了上述解决方法一所保存的模型)多GPU下保存的权重无法在单GPU/CPU下运行,预测时可以创建多GPU模型后先导入多GPU的权重而用template model 进行predict:

model = get_model()
paralleled_model=multi_gpu_model(model,gpus=num_gpu)
paralleled_model.load_weights("weights_multi_gpu.h5") # 此时model也自动载入了权重,可用model进行预测
model.predict()

参考

https://www.jianshu.com/p/d57595dac5a9

https://www.jianshu.com/p/4ab64566cf76

这篇关于【Keras】多GPU训练和模型保存的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112414

相关文章

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

Spring AI Alibaba接入大模型时的依赖问题小结

《SpringAIAlibaba接入大模型时的依赖问题小结》文章介绍了如何在pom.xml文件中配置SpringAIAlibaba依赖,并提供了一个示例pom.xml文件,同时,建议将Maven仓... 目录(一)pom.XML文件:(二)application.yml配置文件(一)pom.xml文件:首

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

如何在本地部署 DeepSeek Janus Pro 文生图大模型

《如何在本地部署DeepSeekJanusPro文生图大模型》DeepSeekJanusPro模型在本地成功部署,支持图片理解和文生图功能,通过Gradio界面进行交互,展示了其强大的多模态处... 目录什么是 Janus Pro1. 安装 conda2. 创建 python 虚拟环境3. 克隆 janus

本地私有化部署DeepSeek模型的详细教程

《本地私有化部署DeepSeek模型的详细教程》DeepSeek模型是一种强大的语言模型,本地私有化部署可以让用户在自己的环境中安全、高效地使用该模型,避免数据传输到外部带来的安全风险,同时也能根据自... 目录一、引言二、环境准备(一)硬件要求(二)软件要求(三)创建虚拟环境三、安装依赖库四、获取 Dee

DeepSeek模型本地部署的详细教程

《DeepSeek模型本地部署的详细教程》DeepSeek作为一款开源且性能强大的大语言模型,提供了灵活的本地部署方案,让用户能够在本地环境中高效运行模型,同时保护数据隐私,在本地成功部署DeepSe... 目录一、环境准备(一)硬件需求(二)软件依赖二、安装Ollama三、下载并部署DeepSeek模型选

vscode保存代码时自动eslint格式化图文教程

《vscode保存代码时自动eslint格式化图文教程》:本文主要介绍vscode保存代码时自动eslint格式化的相关资料,包括打开设置文件并复制特定内容,文中通过代码介绍的非常详细,需要的朋友... 目录1、点击设置2、选择远程--->点击右上角打开设置3、会弹出settings.json文件,将以下内

Golang的CSP模型简介(最新推荐)

《Golang的CSP模型简介(最新推荐)》Golang采用了CSP(CommunicatingSequentialProcesses,通信顺序进程)并发模型,通过goroutine和channe... 目录前言一、介绍1. 什么是 CSP 模型2. Goroutine3. Channel4. Channe

Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)

《Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)》:本文主要介绍Python基于火山引擎豆包大模型搭建QQ机器人详细的相关资料,包括开通模型、配置APIKEY鉴权和SD... 目录豆包大模型概述开通模型付费安装 SDK 环境配置 API KEY 鉴权Ark 模型接口Prompt