导包
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings('ignore')
import matplotlib.pyplot as plt
import seaborn as sns
加载数据
image_train=np.load('train.npy')
image_test=np.load('test.npy')
#方便查看
pd.set_option('max_columns',None)
key_point=pd.read_csv('train.csv')
#transpose,改变轴,除以255是归一化
image_train = np.transpose(image_train, [2, 0, 1]) / 255
image_test = np.transpose(image_test, [2, 0, 1]) / 255
可视化图片
random_number=np.random.randint(0,5000)
XY=key_point.iloc[random_number,:].values.reshape(-1,2)
plt.scatter(XY[:,0],XY[:,1])
plt.imshow(image_train[random_number],cmap='gray')
统计关键点分布规律
fig,axes = plt.subplots(4,2,figsize=(8,14))
for i,ax in enumerate(axes.flatten()):
sns.boxplot(key_point.iloc[:,i],ax=ax)
缺失值填充
#查看缺失比例
key_point.isna().sum()
#众数填充
key_point=key_point.fillna(key_point.mode().iloc[0,:],axis=0)
sklearn全连接网络
from sklearn.multioutput import MultiOutputRegressor
from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error
x_train,x_test,y_train,y_test=train_test_split(image_train,key_point,test_size=0.2,random_state=0)
#多输出回归
mor = MultiOutputRegressor(
MLPRegressor(random_state=2021, early_stopping=True,
max_iter=10)).fit(x_train.reshape(x_train.shape[0], -1),
y_train)
y_val_pred_sk_mlp=mor.predict(x_test.reshape(x_test.shape[0], -1))
#查看得分:8.578599745354985
mean_absolute_error(y_test,y_val_pred_sk_mlp)
y_test_pred_sk_mlp=mor.predict(image_test.reshape(image_test.shape[0],-1))
keras全连接网络
from keras import models,layers
from keras import backend as K
from keras import callbacks
from tensorflow.keras import optimizers
#其实可以在最后的输出层用8来代替
K.clear_session()
model_full_con = models.Sequential()
model_full_con.add(layers.Flatten(input_shape=(96, 96)))
model_full_con.add(layers.Dropout(0.2))
model_full_con.add(layers.Dense(512, activation='relu'))
model_full_con.add(layers.Dropout(0.2))
model_full_con.add(layers.Dense(128, activation='relu'))
model_full_con.add(layers.Dropout(0.2))
model_full_con.add(layers.Dense(8))
model_full_con.compile(optimizer=optimizers.Adam(0.001),
loss='mse',
metrics=['mae'])
#模型可视化
from tensorflow.keras.utils import plot_model
plot_model(model_full_con)
#训练模型
model_full_con.fit(
image_train,
key_point.values,
epochs=1000,
validation_split=0.1,
callbacks=[callbacks.EarlyStopping(patience=10)]
)
#预测模型
y_val_pred_kr_con=model_full_con.predict(image_train)
#得分:2.490596283609673
mean_absolute_error(key_point,y_val_pred_kr_con)
y_test_pred_kr_con=model_full_con.predict(image_test)
卷积神经网络
#把数据整理成所需格式
image_test_=image_test.reshape(2049,96,96,1)
image_train_=image_train.reshape(5000,96,96,1)
K.clear_session()
model_conv = models.Sequential()
model_conv.add(layers.Conv2D(64,(3,3),input_shape=(96,96,1),activation='relu'))
model_conv.add(layers.MaxPooling2D((2,2)))
model_conv.add(layers.Conv2D(64,(3,3),activation='relu'))
model_conv.add(layers.MaxPooling2D((2,2)))
model_conv.add(layers.Flatten())
model_conv.add(layers.Dense(512,activation='relu'))
model_conv.add(layers.Dropout(0.2))
model_conv.add(layers.Dense(128,activation='relu'))
model_conv.add(layers.Dropout(0.2))
model_conv.add(layers.Dense(8))
model_conv.compile(optimizer='adam', loss='mae', metrics=['mse'])
#模型概览
model_conv.summary()
model_conv.fit(image_train_,
key_point,
validation_split=0.1,
callbacks=[callbacks.EarlyStopping(patience=3)],
epochs=5)
y_val_pred_kr_conv=model_conv.predict(image_train_)
#得分:4.121352594790027
mean_absolute_error(key_point,y_val_pred_kr_conv)
y_test_pred_kr_conv=model_conv.predict(image_test_)
与训练模型 ,ResNet18
from tensorflow.keras.applications import ResNet50
K.clear_session()
ResNet50_base = ResNet50(include_top=False,
input_shape=(96, 96, 1),
weights=None)
model_rnt = models.Sequential()
model_rnt.add(ResNet50_base)
model_rnt.add(layers.Flatten())
model_rnt.add(layers.Dropout(0.2))
model_rnt.add(layers.Dense(512, activation='relu'))
model_rnt.add(layers.Dropout(0.2))
model_rnt.add(layers.Dense(128, activation='relu'))
model_rnt.add(layers.Dropout(0.2))
model_rnt.add(layers.Dense(8))
model_rnt.compile(optimizer='rmsprop', loss='mae', metrics=['mse'])
model_rnt.fit(image_train_, key_point, validation_split=0.1, epochs=5)
y_val_pred_ResNet=model_rnt.predict(image_train_)
#得分:11.004968372064829
mean_absolute_error(key_point,y_val_pred_ResNet)
y_test_pred_ResNet=model_rnt.predict(image_test_)
模型集成
from sklearn.linear_model import LinearRegression
y_pred_jc=np.zeros((5000,8))
y_set = np.zeros((2049, 8))
for i in tqdm(range(8)):
y_val = np.concatenate([
y_val_pred_kr_con[:, i:i + 1], y_val_pred_kr_conv[:, i:i + 1],
y_val_pred_ResNet[:, i:i + 1]
],
axis=1)
y = key_point.values[:, i:i + 1]
y_pred_tem = np.concatenate([
y_test_pred_kr_con[:, i:i + 1], y_test_pred_kr_conv[:, i:i + 1],
y_test_pred_ResNet[:, i:i + 1]
],
axis=1)
#cre_model
lr = LinearRegression().fit(y_val, y)
y_pred_jc[:,i]=lr.predict(y_val).flatten()
y_set[:,i]=lr.predict(y_pred_tem).flatten()
#得分:2.300328768225613
mean_absolute_error(key_point,y_pred_jc)
伪标签
#简单点讲,伪标签就是用预测的结果来预测下一次结果,一般用在cv里
image_false_label=np.concatenate([image_train_,image_test_],axis=0)
y_false_label=np.concatenate([y_val_pred_kr_conv,y_test_pred_kr_conv],axis=0)
K.clear_session()
model_fal_label=models.Sequential()
model_fal_label.add(layers.Conv2D(64,(3,3),input_shape=(96,96,1),activation='relu'))
model_fal_label.add(layers.MaxPool2D(2))
model_fal_label.add(layers.Conv2D(128,(3,3),activation='relu'))
model_fal_label.add(layers.MaxPool2D(2))
model_fal_label.add(layers.Conv2D(64,(3,3),activation='relu'))
model_fal_label.add(layers.MaxPool2D(2))
model_fal_label.add(layers.Conv2D(32,(3,3),activation='relu'))
model_fal_label.add(layers.MaxPool2D(2))
model_fal_label.add(layers.Flatten())
model_fal_label.add(layers.Dense(512,activation='relu'))
model_fal_label.add(layers.Dropout(0.2))
model_fal_label.add(layers.Dense(128,activation='relu'))
model_fal_label.add(layers.Dropout(0.2))
model_fal_label.add(layers.Dense(8))
model_fal_label.compile(optimizer='adam',loss=['mae'],metrics=['mse'])
model_fal_label.fit(image_false_label,y_false_label,epochs=10,validation_split=0.2)
y_val_pred_fal_label=model_fal_label.predict(image_train_)
#得分:5.163651354347177
mean_absolute_error(key_point,y_val_pred_fal_label)
y_test_pred_fal_label=model_fal_label.predict(image_test_)
模型蒸馏
'''
模型蒸馏:
简单点说就是好模型的输出当作较好模型的label
深奥点,其实我没太懂
'''
#老师模型
def get_teacher_model():
model_teacher=models.Sequential()
model_teacher.add(layers.Conv2D(64,(3,3),input_shape=(96,96,1),activation='relu'))
model_teacher.add(layers.MaxPool2D(2))
model_teacher.add(layers.Conv2D(128,(3,3),activation='relu'))
model_teacher.add(layers.MaxPool2D(2))
model_teacher.add(layers.Conv2D(64,(3,3),activation='relu'))
model_teacher.add(layers.MaxPool2D(2))
model_teacher.add(layers.Conv2D(32,(3,3),activation='relu'))
model_teacher.add(layers.MaxPool2D(2))
model_teacher.add(layers.Flatten())
model_teacher.add(layers.Dense(8))
model_teacher.compile(optimizer='adam',loss='mae',metrics=['mse'])
return model_teacher
t_model=get_teacher_model()
t_model.fit(image_train_,key_point,epochs=5,validation_split=0.2)
#得分:3.193332656193553
t_model_y_val=t_model.predict(image_train_)
t_model_y_test=t_model.predict(image_test_)
#学生模型
def get_student_model():
model_student=models.Sequential()
model_student.add(layers.Flatten(input_shape=(96,96,1)))
model_student.add(layers.Dense(512,activation='relu'))
model_student.add(layers.Dense(128,activation='relu'))
model_student.add(layers.Dense(8))
model_student.compile(optimizer='adam',loss='mae',metrics=['mse'])
return model_student
s_model=get_student_model()
s_model.fit(image_train_,key_point,epochs=5,validation_split=0.2)
#得分:7.92631005673819
s_model_y_val=s_model.predict(image_train_)
s_model_y_test=s_model.predict(image_test_)
#蒸馏过程
def teach_student(teacher_out, student_model, data_train, data_test, ture_kp):
t_out = teacher_out #通过教师模型生成的软标签
#传入学生模型
s_model = student_model
for l in s_model.layers:
l.trainable = True#设置学生模型的所有层都可以训练
#实例化学生网络,定义输入输出,其输入是(96,96,1)
model = models.Model(s_model.input, s_model.output)
#学生网络进行编译
model.compile(loss="mae",
optimizer="adam")
#t_out是老师模型的输出,入训练集数据和软标签,进行网络蒸馏训练
model.fit(data_train, t_out, epochs=5)
#根据老师模型的输出,的出结果
y_tem= model.predict(data_train)
#计算测试集的准确度
print(mean_absolute_error(ture_kp, y_tem))
zl_y=model.predict(data_test)
return model,zl_y
#得分:7.260453643360854,学生模型有进步
t_s_model, y_test_pred_zl = teach_student(t_model_y_val, s_model, image_train_,
image_test_, key_point)