如何将Keras模型权重转换为一维数组?
问题:将Keras InceptionV3模型权重转换为一维数组失败
问题背景
基于Keras构建的InceptionV3模型处理MNIST数据集的代码:
x_train_mnist = np.expand_dims(x_train_mnist, axis=-1) x_train_mnist = np.repeat(x_train_mnist, 3, axis=-1) x_train_mnist = x_train_mnist.astype('float32') / 255 x_train_mnist = tf.image.resize(x_train_mnist, [75,75]) x_test_mnist = np.expand_dims(x_test_mnist, axis=-1) x_test_mnist = np.repeat(x_test_mnist, 3, axis=-1) x_test_mnist = x_test_mnist.astype('float32') / 255 x_test_mnist = tf.image.resize(x_test_mnist, [75,75]) model=tf.keras.applications.InceptionV3( include_top=True, pooling=None, classes=10, weights=None, input_shape=(75,75,3) )
尝试转换权重为一维数组时执行以下代码出错:
weights=model.weights print(type(weights)) weights_np=np.array(weights) print(type(weights_np)) weights_npfloat_32=np.float32(weights_np) print(weights_np.size)
错误输出:
<class 'list'> <class 'numpy.ndarray'> /tmp/ipykernel_3796671/1208296518.py:3: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray. weights_np=np.array(weights) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) File ~/miniconda3/lib/python3.9/site-packages/tensorflow/python/ops/resource_variable_ops.py:1456, in BaseResourceVariable.__float__(self) 1455 def __float__(self): -> 1456 return float(self.value().numpy()) TypeError: only size-1 arrays can be converted to Python scalars The above exception was the direct cause of the following exception: ValueError Traceback (most recent call last) Cell In [42], line 5 3 weights_np=np.array(weights) 4 print(type(weights_np)) ----> 5 weights_npf=np.float32(weights_np) 6 print(weights_np.size) ValueError: setting an array element with a sequence.
错误原因
model.weights返回的是TensorFlow ResourceVariable对象的列表,并非直接的numpy数组,直接转换会生成存储对象的numpy数组,无法直接转为float32类型- 每个权重变量的形状各不相同,直接用
np.array(weights)会生成不规则数组(ragged array),触发警告且后续类型转换失败
解决方案
需要先将每个权重变量转为numpy数组并展平,再合并为一个一维数组:
import numpy as np # 遍历所有权重,逐个转换为numpy数组并展平 flattened_weights = [] for weight_var in model.weights: # 将TensorFlow变量转为numpy数组,再展平为一维 weight_np = weight_var.numpy().flatten() flattened_weights.append(weight_np) # 合并所有一维数组为一个大的行向量 weights_1d = np.concatenate(flattened_weights) # 验证结果 print(f"类型:{type(weights_1d)}") print(f"形状:{weights_1d.shape}") # 输出形如(总权重数量,)的一维数组 print(f"数据类型:{weights_1d.dtype}") # 应为float32
代码说明
- 遍历
model.weights中的每个变量,用weight_var.numpy()将TensorFlow变量转为numpy数组,再通过flatten()将其转为一维数组 - 使用
np.concatenate将所有一维数组合并成一个连续的行向量,最终得到包含所有模型权重的一维数组
内容的提问来源于stack exchange,提问作者CA Khan
相关产品推荐
相关产品推荐

