【问题标题】:Getting weights and biases from a CNN model and saving them into csv file从 CNN 模型中获取权重和偏差并将它们保存到 csv 文件中
【发布时间】:2020-03-13 05:39:30
【问题描述】:

我最近为 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         
=================================================================

总参数:973,845 可训练参数:973,845 不可训练参数: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”中,用于所有卷积层和密集层。有人可以帮忙吗?

提前致谢

【问题讨论】:

  • 如果使用内置方法model.save_weights(filepath)不是更方便吗?再次加载这些权重会更容易。
  • 感谢您的评论,但我的目的是分别保存每个卷积层和密集层的权重和偏差,例如 conv layer 1 的“weights.csv”和“bias.csv”,“ weights2.csv' 和 'bias2.csv' 用于 conv 2nd 层或密集层,对于模型中的所有卷积层和密集层都是如此。想要 .csv 文件中每一层的权重和偏差。

标签: python-3.x tensorflow keras


【解决方案1】:

要获得 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 中。如果您以后想再次加载这些权重,这将对您有所帮助。

【讨论】:

  • 再次感谢您的帮助,但它会将所有层的权重和偏差保存在一个“weight.csv”和“bias.csv”文件中吗?
  • 这个循环遍历所有层,所以对于每一层,你都会得到权重和偏差。您可以将其保存为您想要的格式,单独或组合。
  • 您是否还可以添加我将保存每一层的权重和偏差的部分,例如,在一个“weights.csv”或'bias.csv' 文件在循环内部还是外部?。例如,对于 conv2d_5 层,使用循环或在其外部分离 weights.csv 和 bias.csv 文件。这将再次提供巨大的帮助。
  • 非常感谢,我看看能否成功实现代码。如果我在这方面遇到更多错误,我会在 cmets 中通知您。再次感谢:)
  • 您的代码完美运行:)。但另外一件事是,在 weights.csv 和 bias.csv 中,权重和偏差位于单列(我假设为单层)和不同的行中。如果我要将文件中的偏差或权重放在一个层的单行和不同列中,即对于特定的bias.csv 或 weights.csv 文件,可以做什么?到现在为止你是一个巨大的帮助,再次感谢
猜你喜欢
  • 2022-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
  • 1970-01-01
  • 2019-08-04
相关资源
最近更新 更多