TensorFlow Keras跨品类产品ID预测模型不学习准确率极低求助
模型不学习的原因与优化方案
核心问题诊断
- 损失与激活函数不符合任务定位:你要解决的是单标签多分类任务(输入1个T恤ID,输出唯一匹配的针织帽ID),当前输出层用
sigmoid激活+binary_crossentropy损失是多标签分类的配置,逻辑完全不匹配,导致模型无法得到正确的梯度更新信号。 - 稀疏输入学习效率低:独热编码的输入向量维度高、有效信息密度极低,模型很难从稀疏特征中学习到两类产品的映射关系。
- 激活函数导致梯度消失:中间层全用
sigmoid激活,多层叠加后很容易出现梯度饱和消失的问题,参数长时间得不到更新,自然不会学习。
是否需要用Embedding层?
需要,Embedding层是处理ID类特征的最优选择之一:
- 可以直接接收整数类型的ID编码作为输入,不需要提前做独热编码,节省内存和预处理步骤
- 能将高维稀疏的ID映射为低维稠密的特征向量,大幅降低模型参数规模,同时可以学习到不同产品之间的隐含关联特征。
具体优化代码
import pandas as pd from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Input, Dense, Embedding, Flatten, Dropout from tensorflow.keras.optimizers import Adam from tensorflow.keras.utils import to_categorical from sklearn.model_selection import train_test_split def import_data(url): dataframe = pd.read_csv(url) return dataframe def prepare_df(dataframe): split_data = dataframe['product_ids'].str.split(',', n=1, expand=True) split_data = split_data.rename(columns={0: 'Beanie', 1: 'Shirt'}) split_data = split_data.dropna() split_data['Beanie'] = pd.to_numeric(split_data["Beanie"]).astype('category').cat.codes split_data['Shirt'] = pd.to_numeric(split_data['Shirt']).astype('category').cat.codes return split_data def create_model(shirt_count=127, beanie_count=607, emb_dim=16): my_model = Sequential() # 输入为整数ID,加Embedding层处理 my_model.add(Input(shape=(1,))) my_model.add(Embedding(input_dim=shirt_count, output_dim=emb_dim, input_length=1)) my_model.add(Flatten()) # 中间层用ReLU激活避免梯度消失 my_model.add(Dense(64, activation='relu')) my_model.add(Dropout(0.2)) # 加Dropout防止过拟合 my_model.add(Dense(32, activation='relu')) # 输出层用softmax适配多分类任务 my_model.add(Dense(beanie_count, activation='softmax')) return my_model if __name__ == '__main__': data = import_data('data/_Data_Beanies_Shirts_2.csv') data = prepare_df(data) X = data['Shirt'] y = data['Beanie'] # 不需要给X转独热,直接用整数ID输入即可 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1, shuffle=True) y_train = to_categorical(y_train, num_classes=607) y_test = to_categorical(y_test, num_classes=607) optimizer = Adam(learning_rate=0.001) model = create_model() # 损失函数换为多分类交叉熵 model.compile( loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'] ) print("Fit model on training data") history = model.fit( x=X_train, y=y_train, epochs=50, verbose=1, validation_data=(X_test, y_test), batch_size=8 # 小批次更新训练更稳定 )
额外调优建议
- 如果你的数据集本身是1对1的配对关系,每个T恤ID只对应唯一的针织帽ID,那这个任务本质是映射查表,优化后模型准确率会接近100%;如果是1对多的配对,可以在评估的时候取top3/top5准确率来衡量效果,更贴合业务实际。
- Embedding的维度可以根据产品数量调整,产品越多可以适当调高维度,一般在8~64区间即可。
- 训练的时候如果发现验证集准确率上升后下降,说明出现过拟合,可以调大Dropout比例,或者提前停止训练。
内容的提问来源于stack exchange,提问作者pybugHTL
相关产品推荐
相关产品推荐

