ValueError: Shape must be rank 0 but is rank 1 for ‘Adam/update_weight/ApplyAdam‘ (op: ‘ApplyAdam‘)

在使用TensorFlow时遇到ValueError,指出'Adam/update_weight/ApplyAdam'操作需要rank 0张量,但提供了rank 1的self.lr。原因是自定义的lr变量是形状为[1]的向量,而AdamOptimizer期望的是标量。解决方案是将lr变量改为标量。

原代码:

self.lr = tf.placeholder(shape=[1],dtype=tf.float32,name="learning_rate")
。。。
。。。
        
optimizer = tf.train.AdamOptimizer(learning_rate=self.lr)
self.trainops = optimizer.minimize(self.cost)                                                                       
    

报错信息:

InvalidArgumentError: Shape must be rank 0 but is rank 1 for 'Adam/update_weight/ApplyAdam' (op: 'ApplyAdam') with input shapes: [39,2], [39,2], [39,2], [], [], [1], [], [], [], [39,2].
During handling of the above exception, another exception occurred:
ValueError                                Traceback (most recent call last)
<ipython-input-149-f2a8d1d94ea1> in __init__(self)
     29 
     30         optimizer = tf.train.AdamOptimizer(learning_rate=self.lr)
---> 31         self.trainops = optimizer.minimize(self.cost)

出错原因:自定义的变量self.lr的shape为[1],即vector(rank 1 tesnsor),而tf.train.AdamOptimizer中learning_rate只

import tensorflow as tf import numpy as np # import matplotlib.pyplot as plt from prepare import load_and_preprocess_data from tensorflow.keras import layers, Model, regularizers class FeatureGrouping(layers.Layer): """特征分组层:将输入特征按类型分组""" def __init__(self, group_config, **kwargs): """ group_config: 分组配置字典,例如{'group1': [0,1,2], 'group2': [3,4,5]} """ super(FeatureGrouping, self).__init__(**kwargs) self.group_config = group_config self.group_names = list(group_config.keys()) def call(self, inputs): """将输入特征按配置分组""" grouped_features = {} for group_name, indices in self.group_config.items(): grouped_features[group_name] = tf.gather(inputs, indices, axis=1) return grouped_features class FeatureEmbedding(layers.Layer): """特征嵌入层:为每个特征组创建嵌入表示""" def __init__(self, embedding_dims, **kwargs): """ embedding_dims: 每个组的嵌入维度字典,例如{'group1': 16, 'group2': 32} """ super(FeatureEmbedding, self).__init__(**kwargs) self.embedding_dims = embedding_dims self.embedding_layers = {} def build(self, input_shapes): """为每个特征组创建嵌入层""" for group_name, shape in input_shapes.items(): dim = self.embedding_dims[group_name] self.embedding_layers[group_name] = layers.Dense( dim, activation='relu', name=f'embed_{group_name}') super().build(input_shapes) def call(self, inputs): """应用嵌入转换""" embeddings = {} for group_name, features in inputs.items(): embeddings[group_name] = self.embedding_layers[group_name](features) return embeddings class MultiHeadSelfAttention(layers.Layer): """多头自注意力机制""" def __init__(self, num_heads, key_dim, **kwargs): super(MultiHeadSelfAttention, self).__init__(**kwargs) self.mha = layers.MultiHeadAttention( num_heads=num_heads, key_dim=key_dim) self.norm = layers.LayerNormalization(epsilon=1e-6) self.add = layers.Add() def call(self, inputs): """应用多头自注意力""" attn_output = self.mha(query=inputs, value=inputs, key=inputs) out = self.add([inputs, attn_output]) return self.norm(out) class PhysicsConstrainedModel(Model): """物理约束融合模型""" def __init__(self, group_config, embedding_dims, num_heads, key_dim, output_dim, physics_constraint_fn, constraint_weight=0.1, **kwargs): """ physics_constraint_fn: 物理约束函数,接受输入和预测输出,返回约束损失 constraint_weight: 物理约束的权重系数 """ super(PhysicsConstrainedModel, self).__init__(**kwargs) self.grouping = FeatureGrouping(group_config) self.embedding = FeatureEmbedding(embedding_dims) self.attention_layers = {} # 为每个组创建自注意力层 for group_name in group_config.keys(): self.attention_layers[group_name] = MultiHeadSelfAttention( num_heads, key_dim) # 融合层和输出层 self.concat = layers.Concatenate() self.dense1 = layers.Dense(64, activation='relu') self.dense2 = layers.Dense(32, activation='relu') self.output_layer = layers.Dense(output_dim) # 物理约束参数 self.physics_constraint_fn = physics_constraint_fn self.constraint_weight = constraint_weight def call(self, inputs): """前向传播""" # 特征分组 grouped = self.grouping(inputs) # 特征嵌入 embedded = self.embedding(grouped) # 应用自注意力 attended = {} for group_name, features in embedded.items(): # 添加位置编码 seq_length = tf.shape(features)[1] positions = tf.range(start=0, limit=seq_length, delta=1) positions = tf.cast(positions, dtype=tf.float32) positions = tf.expand_dims(positions, axis=0) # (1, seq_length) positions = tf.tile(positions, [tf.shape(features)[0], 1]) # (batch, seq_length) positions = tf.expand_dims(positions, axis=-1) # (batch, seq_length, 1) # 合并特征和位置编码 features_with_pos = tf.concat([features, positions], axis=-1) attended[group_name] = self.attention_layers[group_name](features_with_pos) # 池化每个组的特征 pooled = [layers.GlobalAveragePooling1D()(feat) for feat in attended.values()] # 特征融合 fused = self.concat(pooled) x = self.dense1(fused) x = self.dense2(x) return self.output_layer(x) def train_step(self, data): """自定义训练步骤,包含物理约束""" x, y = data with tf.GradientTape() as tape: # 前向传播 y_pred = self(x, training=True) # 计算主损失 main_loss = self.compiled_loss(y, y_pred) # 计算物理约束损失 physics_loss = self.physics_constraint_fn(x, y_pred) # 总损失 = 主损失 + 约束损失 total_loss = main_loss + self.constraint_weight * physics_loss # 计算梯度并更新权重 trainable_vars = self.trainable_variables gradients = tape.gradient(total_loss, trainable_vars) self.optimizer.apply_gradients(zip(gradients, trainable_vars)) # 更新指标 self.compiled_metrics.update_state(y, y_pred) # 返回指标 return {m.name: m.result() for m in self.metrics} # 示例物理约束函数:能量守恒约束 def energy_conservation_constraint(inputs, predictions): """ 简单的能量守恒约束:输入的总和应等于输出的总和 在实际应用中,应根据具体物理规律设计约束 """ input_sum = tf.reduce_sum(inputs, axis=1, keepdims=True) output_sum = tf.reduce_sum(predictions, axis=1, keepdims=True) return tf.reduce_mean(tf.square(input_sum - output_sum)) # 生成模拟数据 def generate_data(num_samples=1000, input_dim=10): """生成模拟数据""" # 随机输入特征 X = np.random.randn(num_samples, input_dim).astype(np.float32) # 目标输出:输入特征的线性组合加噪声 weights = np.random.randn(input_dim, 1) y = X @ weights + 0.1 * np.random.randn(num_samples, 1) return X, y # 配置参数 INPUT_DIM = 10 OUTPUT_DIM = 1 NUM_SAMPLES = 10000 BATCH_SIZE = 32 EPOCHS = 50 # 特征分组配置 GROUP_CONFIG = { 'group1': [0, 1, 2, 3], # 第一组特征索引 'group2': [4, 5, 6], # 第二组特征索引 'group3': [7, 8, 9] # 第三组特征索引 } # 嵌入维度配置 EMBEDDING_DIMS = { 'group1': 16, 'group2': 16, 'group3': 16 } # 注意力参数 NUM_HEADS = 4 KEY_DIM = 8 # 物理约束权重 CONSTRAINT_WEIGHT = 0.1 # 生成数据 X_train, y_train = generate_data(NUM_SAMPLES, INPUT_DIM) print(f"训练数据形状: {X_train.shape}, 目标数据形状: {y_train.shape}") # X_train, X_test, y_train, y_test, preprocessor = load_and_preprocess_data('E:\\神经网络\\分类数据集.xlsx') # 替换为实际文件路径 # 创建模型 model = PhysicsConstrainedModel( group_config=GROUP_CONFIG, embedding_dims=EMBEDDING_DIMS, num_heads=NUM_HEADS, key_dim=KEY_DIM, output_dim=OUTPUT_DIM, physics_constraint_fn=energy_conservation_constraint, constraint_weight=CONSTRAINT_WEIGHT ) # 编译模型 model.compile( optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), loss='mse', metrics=['mae'] ) # 训练模型 print("开始训练物理约束模型...") history = model.fit( X_train, y_train, batch_size=BATCH_SIZE, epochs=EPOCHS, validation_split=0.2 ) # 评估模型 test_loss, test_mae = model.evaluate(X_train[:100], y_train[:100]) print(f"\n测试损失: {test_loss:.4f}, 测试MAE: {test_mae:.4f}") # 可视化训练过程 # plt.figure(figsize=(12, 5)) # plt.subplot(1, 2, 1) # plt.plot(history.history['loss'], label='训练损失') # plt.plot(history.history['val_loss'], label='验证损失') # plt.title('模型损失') # plt.ylabel('损失') # plt.xlabel('Epoch') # plt.legend() # plt.subplot(1, 2, 2) # plt.plot(history.history['mae'], label='训练MAE') # plt.plot(history.history['val_mae'], label='验证MAE') # plt.title('平均绝对误差') # plt.ylabel('MAE') # plt.xlabel('Epoch') # plt.legend() # plt.tight_layout() # plt.show() # 模型结构可视化 tf.keras.utils.plot_model( model, to_file='physics_constrained_model.png', show_shapes=True, show_layer_names=True ) 上面这段代码在运行时出现 Traceback (most recent call last): File "e:\神经网络\multi-head-attention.py", line 226, in <module> history = model.fit( File "C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1193, in fit tmp_logs = self.train_function(iterator) File "C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\eager\def_function.py", line 885, in __call__ result = self._call(*args, **kwds) File "C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\eager\def_function.py", line 933, in _call self._initialize(args, kwds, add_initializers_to=initializers) File "C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\eager\def_function.py", line 759, in _initialize self._stateful_fn._get_concrete_function_internal_garbage_collected( # pylint: disable=protected-access File "C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\eager\function.py", line 3066, in _get_concrete_function_internal_garbage_collected graph_function, _ = self._maybe_define_function(args, kwargs) File "C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\eager\function.py", line 3463, in _maybe_define_function graph_function = self._create_graph_function(args, kwargs) File "C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\eager\function.py", line 3298, in _create_graph_function func_graph_module.func_graph_from_py_func( File "C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\framework\func_graph.py", line 1007, in func_graph_from_py_func func_outputs = python_func(*func_args, **func_kwargs) File "C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\eager\def_function.py", line 668, in wrapped_fn out = weak_wrapped_fn().__wrapped__(*args, **kwds) File "C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\framework\func_graph.py", line 994, in wrapper raise e.ag_error_metadata.to_exception(e) ValueError: in user code: C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\keras\engine\training.py:862 train_function * return step_function(self, iterator) e:\神经网络\multi-head-attention.py:112 call * features_with_pos = tf.concat([features, positions], axis=-1) C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\util\dispatch.py:206 wrapper ** return target(*args, **kwargs) C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\ops\array_ops.py:1769 concat return gen_array_ops.concat_v2(values=values, axis=axis, name=name) C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\ops\gen_array_ops.py:1226 concat_v2 _, _, _op, _outputs = _op_def_library._apply_op_helper( C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\framework\op_def_library.py:748 _apply_op_helper op = g._create_op_internal(op_type_name, inputs, dtypes=None, C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\framework\func_graph.py:599 _create_op_internal return super(FuncGraph, self)._create_op_internal( # pylint: disable=protected-access C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\framework\ops.py:3561 _create_op_internal ret = Operation( C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\framework\ops.py:2041 __init__ self._c_op = _create_c_op(self._graph, node_def, inputs, C:\Users\Administrator\.conda\envs\ens\lib\site-packages\tensorflow\python\framework\ops.py:1883 _create_c_op raise ValueError(str(e)) ValueError: Shape must be rank 2 but is rank 3 for '{{node physics_constrained_model/concat}} = ConcatV2[N=2, T=DT_FLOAT, Tidx=DT_INT32](physics_constrained_model/feature_embedding/embed_group1/Relu, physics_constrained_model/ExpandDims_1, physics_constrained_model/concat/axis)' with input shapes: [32,16], [32,16,1], [].,请帮我解决代码问题
最新发布
08-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值