这个错误提示表明你的代码中引用了一个未定义的变量 model
。看起来是因为在定义模型的最后部分代码中缺少了括号,导致 model
变量没有被正确定义。
以下是修正后的代码:
import tensorflow as tf
from tensorflow.keras.layers import Layer, Conv2D, Dense, Input, Reshape
from tensorflow.keras.models import Model
from tensorflow.keras.datasets import mnist
import numpy as np
import matplotlib.pyplot as plt
# 加载并准备MNIST数据集
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28, 28, 1)).astype('float32') / 255
test_images = test_images.reshape((10000, 28, 28, 1)).astype('float32') / 255
# 定义胶囊层
class CapsuleLayer(Layer):
def __init__(self, num_capsules, dim_capsule, routings, **kwargs):
super(CapsuleLayer, self).__init__(**kwargs)
self.num_capsules = num_capsules
self.dim_capsule = dim_capsule
self.routings = routings
def build(self, input_shape):
# input_shape: (batch_size, height, width, channels)
self.kernel = self.add_weight(
shape=[input_shape[-1], self.num_capsules * self.dim_capsule],
initializer='glorot_uniform',
trainable=True,
name='capsule_kernel'
)
def call(self, inputs):
# inputs: (batch_size, height, width, channels)
# Reshape inputs to (batch_size, height * width, channels)
x = tf.reshape(inputs, (tf.shape(inputs)[0], -1, inputs.shape[-1]))
# Calculate u_hat
u_hat = tf.matmul(x, self.kernel)
u_hat = tf.reshape(u_hat, (tf.shape(u_hat)[0], -1, self.num_capsules, self.dim_capsule))
# Initialize the Logits (b) as zeros
b = tf.zeros((tf.shape(inputs)[0], self.num_capsules), dtype=tf.float32)
# Routing algorithm
for i in range(self.routings):
c = tf.nn.softmax(b, axis=1) # Softmax over the capsules
s = tf.matmul(tf.reshape(c, (tf.shape(c)[0], -1, 1)), u_hat, transpose_b=True) # Weighted sum of u_hat vectors
s = tf.squeeze(s, 2) # Remove the singleton dimension
v = tf.nn.squash(s) # Squash the vector
b = b + tf.reduce_sum(v, axis=2) # Update the logits
# Squash the final vectors
v = tf.nn.squash(b[..., tf.newaxis])
return tf.reshape(v, (tf.shape(inputs)[0], -1, self.num_capsules, self.dim_capsule))
def compute_output_shape(self, input_shape):
return (input_shape[0], input_shape[1] * input_shape[2], self.num_capsules, self.dim_capsule)
# 构建胶囊网络模型
inputs = Input(shape=(28, 28, 1))
x = Conv2D(256, kernel_size=9, strides=2, padding='valid')(inputs)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU()(x)
capsule_layer = CapsuleLayer(num_capsules=10, dim_capsule=16, routings=3)
primarycaps = capsule_layer(x)
# 将输出维度调整为 (batch_size, 10)
primarycaps = Reshape((-1, 10))(primarycaps)
outputs = Dense(10, activation='softmax')(primarycaps)
model = Model(inputs=inputs, outputs=outputs) # 确保定义了 model 变量
# 定义损失函数
def margin_loss(y_true, y_pred):
L = y_true * tf.square(tf.maximum(0., 0.9 - y_pred)) + 0.5 * (1 - y_true) * tf.square(tf.maximum(0., y_pred - 0.1))
return tf.reduce_mean(tf.reduce_sum(L, axis=[1, 2]))
model.compile(optimizer='adam', loss=margin_loss, metrics=['accuracy'])
model.summary()
# 训练模型
history = model.fit(train_images, train_labels, epochs=50, validation_data=(test_images, test_labels), batch_size=100)
# 如果需要,还可以绘制训练和验证的损失及准确率曲线
plt.plot