从CNN模型中获取权重和偏差,并将其保存到csv文件中



我最近为cifar 10建立了一个用于图像分类的CNN模型。该模型有效,但我很难为每个可训练层(卷积层和密集层(生成权重和偏差。以下是在构建模型时添加层,然后加载的代码部分

from __future__ import print_function
import keras
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D, AveragePooling2D
from keras.utils.data_utils import Sequence
import os
from keras import backend as K
import numpy as np

def square(x):
return x * x;
batch_size = 64
num_classes = 10
epochs = 500
num_predictions = 20
save_dir = os.path.join(os.getcwd(), 'saved_models')
model_name = 'cifar_model2.h5'
# The data, split between train and test sets:
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train = np.round(x_train/32)/8
x_test = np.round(x_test/32)/8
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
model = Sequential()
model.add(Conv2D(128, (3, 3), padding='same',
input_shape=x_train.shape[1:]))
model.add(AveragePooling2D(pool_size=(2, 2)))
model.add(Conv2D(83, (3, 3)))
model.add(Dropout(0.25))
model.add(Activation(square))
model.add(AveragePooling2D(pool_size=(2, 2)))
model.add(Conv2D(130, (5, 5), padding='same'))
model.add(Activation(square))
model.add(AveragePooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Dense(num_classes))
model.add(Activation('softmax'))
opt = keras.optimizers.Adam(amsgrad=True, decay=0.0001, lr = 0.001)
model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])

print('Using real-time data augmentation.')
datagen = ImageDataGenerator(
featurewise_center=False,  
samplewise_center=False,  
featurewise_std_normalization=False,
samplewise_std_normalization=False, 
zca_whitening=False,  
zca_epsilon=1e-06,  
rotation_range=0,  
width_shift_range=0.1,
height_shift_range=0.1,
shear_range=0.,
zoom_range=0., 
channel_shift_range=0., 
fill_mode='nearest',
cval=0.,
horizontal_flip=True,
vertical_flip=False, 
rescale=None,
preprocessing_function=None,
data_format=None,
validation_split=0.0)
if not os.path.isdir(save_dir):
os.makedirs(save_dir)
model_path = os.path.join(save_dir, model_name)
checkpoint = keras.callbacks.ModelCheckpoint(model_path, monitor='val_loss', verbose=0,    
save_best_only=False, save_weights_only=False, mode='auto', period=10)
callback_list=[checkpoint]
datagen.fit(x_train)
model.fit_generator(datagen.flow(x_train, y_train, batch_size=batch_size), 
callbacks=callback_list,steps_per_epoch=len(x_train)/batch_size,
epochs=epochs, validation_data=(x_test, y_test), workers=4)
# Save 
model.save(model_path)
print('Saved trained model at %s ' % model_path)
scores = model.evaluate(x_test, y_test, verbose=1)
print('Test loss:', scores[0])
print('Test accuracy:', scores[1])

from numpy import loadtxt
from keras.models import load_model
save_dir = os.path.join(os.getcwd(), 'saved_models')
model_name = 'cifar_model2.h5'
model_path = os.path.join(save_dir, model_name)
def square(x):
return x * x;
# load model
model = load_model(model_path, custom_objects={'square': square})]

接下来我输入代码:

model.summary()

用于查看具有参数的所有层(可训练层(。它显示了层次:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_4 (Conv2D)            (None, 32, 32, 128)       3584      
_________________________________________________________________
average_pooling2d_4 (Average (None, 16, 16, 128)       0         
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 14, 14, 83)        95699     
_________________________________________________________________
dropout_3 (Dropout)          (None, 14, 14, 83)        0         
_________________________________________________________________
activation_4 (Activation)    (None, 14, 14, 83)        0         
_________________________________________________________________
average_pooling2d_5 (Average (None, 7, 7, 83)          0         
_________________________________________________________________
conv2d_6 (Conv2D)            (None, 7, 7, 130)         269880    
_________________________________________________________________
activation_5 (Activation)    (None, 7, 7, 130)         0         
_________________________________________________________________
average_pooling2d_6 (Average (None, 3, 3, 130)         0         
_________________________________________________________________
dropout_4 (Dropout)          (None, 3, 3, 130)         0         
_________________________________________________________________
flatten_2 (Flatten)          (None, 1170)              0         
_________________________________________________________________
dense_3 (Dense)              (None, 512)               599552    
_________________________________________________________________
dense_4 (Dense)              (None, 10)                5130      
_________________________________________________________________
activation_6 (Activation)    (None, 10)                0         
=================================================================

参数总数:973845可训练参数:973845不可训练参数:0

现在的问题是,我如何获得每一层的权重和偏差,然后将它们保存在"csv"文件中?。我刚刚使用以下代码获得了单层的权重和偏差:

from numpy import loadtxt
from keras.models import load_model
from keras.engine import InputLayer
output_center=2
input_kernel_range = range(0,10)
input_shape=[14,14,83]
input_maps = input_shape[2]
model_ = Sequential()
model_.add(AveragePooling2D(pool_size=(2, 2),input_shape=[14,14,83]))
model_.add(Conv2D(130, (5, 5), padding='same'))
model_.layers[1].set_weights(model.layers[6].get_weights())
test = np.zeros(input_shape)[np.newaxis,...]
bias = model_.predict(test)[0,output_center,output_center,:]
A = 0
for c in range(0, input_maps):
for y in input_kernel_range:
for x in input_kernel_range:
test = np.zeros(input_shape)[np.newaxis,...]
test[0,x,y,c]=1
prediction = model_.predict(test)
d = prediction[0,output_center,output_center,:] - bias
if (isinstance(A, int)):
A = d
else:
A = np.c_[A, d]
A.tofile("weights.csv", sep=',')
bias.tofile("bias.csv", sep=',')

这只适用于一层。正如我所说,我正在努力获得权重和偏差,并将其保存在所有卷积和密集层的"csv"中。有人能帮忙吗?

提前感谢

要获得Conv2D和Dense层的权重和偏差,可以执行以下操作:

wt = open('weights.csv', 'w')
bs = open('biases.csv', 'w')
for idx,i in enumerate(model.layers):
if(isinstance(i, Conv2D) or isinstance(i, Dense)):
weights = i.get_weights()[0]
biases = i.get_weights()[1]
weights = weights.flatten()
biases = biases.flatten()
print(weights.shape, biases.shape)
wt.write(','.join(map(str,weights.tolist()))+"n")
bs.write(','.join(map(str,biases.tolist()))+"n")
#np.savetxt("weight" + str(idx)+".csv" , weights , fmt='%s', delimiter=',')
#np.savetxt("bias" + str(idx) +".csv" , biases , fmt='%s', delimiter=',')

您还可以跟踪层的原始形状,因为它被展平以存储在CSV中。如果你想在未来再次加载这些重量,这将对你有所帮助。