SHOW:
|
|
- or go back to the newest paste.
1 | import os | |
2 | import pandas as pd | |
3 | import numpy as np | |
4 | import tensorflow as tf | |
5 | from tensorflow.keras.models import Model | |
6 | from tensorflow.keras.layers import Input, Dense, Flatten, Reshape, MultiHeadAttention, LayerNormalization, Dropout, Add, GaussianNoise | |
7 | from tensorflow.keras.optimizers import Adam | |
8 | from tensorflow.keras.regularizers import l1_l2 | |
9 | from tensorflow.keras.callbacks import EarlyStopping | |
10 | from sklearn.model_selection import train_test_split | |
11 | from sklearn.preprocessing import StandardScaler | |
12 | from sklearn.metrics import classification_report | |
13 | import matplotlib.pyplot as plt | |
14 | ||
15 | # 禁用GPU | |
16 | os.environ["CUDA_VISIBLE_DEVICES"] = "-1" | |
17 | tf.config.set_visible_devices([], 'GPU') | |
18 | ||
19 | # 加载本地数据并查看前几行 | |
20 | data = pd.read_csv('/home/xjy/pythonProject/US_Accidents_March23.csv') | |
21 | print("DataFrame 中的列名:", data.columns) | |
22 | print(data.head()) | |
23 | ||
24 | # 假设找到实际的标签列 'Severity' | |
25 | actual_label_column = 'Severity' | |
26 | ||
27 | # 数据预处理 | |
28 | data = data.dropna() | |
29 | features = data.select_dtypes(include=[np.number]) | |
30 | labels = data[actual_label_column] - 1 # 使用正确的列名,假设标签从1开始 | |
31 | ||
32 | scaler = StandardScaler() | |
33 | features = scaler.fit_transform(features) | |
34 | ||
35 | # 按照7:1:2的比例划分训练集、验证集和测试集 | |
36 | X_train, X_temp, y_train, y_temp = train_test_split(features, labels, test_size=0.3, random_state=42) | |
37 | X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.6667, random_state=42) | |
38 | ||
39 | # 输出划分结果 | |
40 | print(f"训练集大小: {X_train.shape[0]}") | |
41 | print(f"验证集大小: {X_val.shape[0]}") | |
42 | print(f"测试集大小: {X_test.shape[0]}") | |
43 | ||
44 | # 构建Transformer模型 | |
45 | def transformer_encoder(inputs, head_size, num_heads, ff_dim, dropout=0): | |
46 | # Multi-Head Attention layer | |
47 | attention = MultiHeadAttention(key_dim=head_size, num_heads=num_heads, dropout=dropout)(inputs, inputs) | |
48 | attention = Add()([attention, inputs]) | |
49 | attention = LayerNormalization(epsilon=1e-6)(attention) | |
50 | ||
51 | # Feed Forward network | |
52 | ff = Dense(ff_dim, activation='relu', kernel_regularizer=l1_l2(l1=0.01, l2=0.01))(attention) | |
53 | ff = Dense(inputs.shape[-1])(ff) | |
54 | ff = Add()([ff, attention]) | |
55 | ff = LayerNormalization(epsilon=1e-6)(ff) | |
56 | return ff | |
57 | ||
58 | input_layer = Input(shape=(X_train.shape[1], 1)) | |
59 | reshape = Reshape((X_train.shape[1], 1))(input_layer) | |
60 | ||
61 | # 增加Transformer编码器层的数量和复杂度 | |
62 | transformer_block = transformer_encoder(reshape, head_size=64, num_heads=4, ff_dim=64, dropout=0.2) | |
63 | transformer_block = transformer_encoder(transformer_block, head_size=64, num_heads=4, ff_dim=64, dropout=0.2) | |
64 | transformer_block = transformer_encoder(transformer_block, head_size=64, num_heads=4, ff_dim=64, dropout=0.2) | |
65 | ||
66 | flatten = Flatten()(transformer_block) | |
67 | noise = GaussianNoise(0.1)(flatten) | |
68 | dense = Dense(64, activation='relu', kernel_regularizer=l1_l2(l1=0.01, l2=0.01))(noise) | |
69 | dropout = Dropout(0.6)(dense) | |
70 | output_layer = Dense(4, activation='softmax')(dropout) | |
71 | ||
72 | model = Model(inputs=input_layer, outputs=output_layer) | |
73 | ||
74 | # 编译模型 | |
75 | model.compile(optimizer=Adam(learning_rate=0.001), loss='sparse_categorical_crossentropy', metrics=['accuracy']) | |
76 | ||
77 | # 训练模型 | |
78 | X_train = np.expand_dims(X_train, axis=-1) | |
79 | X_val = np.expand_dims(X_val, axis=-1) | |
80 | X_test = np.expand_dims(X_test, axis=-1) | |
81 | ||
82 | # 设置 EarlyStopping 回调 | |
83 | early_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True) | |
84 | ||
85 | history = model.fit(X_train, y_train, epochs=50, batch_size=32, validation_data=(X_val, y_val), callbacks=[early_stopping]) | |
86 | ||
87 | # 评估模型 | |
88 | train_acc = history.history['accuracy'][-1] | |
89 | val_acc = history.history['val_accuracy'][-1] | |
90 | test_loss, test_acc = model.evaluate(X_test, y_test) | |
91 | ||
92 | print(f'Training Accuracy: {train_acc}') | |
93 | print(f'Validation Accuracy: {val_acc}') | |
94 | print(f'Test Accuracy: {test_acc}') | |
95 | ||
96 | # 画出 loss 和 accuracy 图 | |
97 | train_loss = history.history['loss'] | |
98 | val_loss = history.history['val_loss'] | |
99 | train_accuracy = history.history['accuracy'] | |
100 | val_accuracy = history.history['val_accuracy'] | |
101 | ||
102 | plt.figure(figsize=(12, 5)) | |
103 | ||
104 | plt.subplot(1, 2, 1) | |
105 | plt.plot(train_loss, label='Training Loss') | |
106 | plt.plot(val_loss, label='Validation Loss') | |
107 | plt.title('Training and Validation Loss Over Epochs') | |
108 | plt.xlabel('Epochs') | |
109 | plt.ylabel('Loss') | |
110 | plt.legend() | |
111 | plt.grid(True) | |
112 | ||
113 | plt.subplot(1, 2, 2) | |
114 | plt.plot(train_accuracy, label='Training Accuracy') | |
115 | plt.plot(val_accuracy, label='Validation Accuracy') | |
116 | plt.title('Training and Validation Accuracy Over Epochs') | |
117 | plt.xlabel('Epochs') | |
118 | plt.ylabel('Accuracy') | |
119 | plt.legend() | |
120 | plt.grid(True) | |
121 | ||
122 | plt.tight_layout() | |
123 | plt.show() | |
124 | ||
125 | # 判断是否过拟合 | |
126 | if train_loss[-1] < val_loss[-1] and train_accuracy[-1] > val_accuracy[-1]: | |
127 | print("可能存在过拟合,因为训练损失明显低于验证损失,且训练准确率高于验证准确率。") | |
128 | else: | |
129 | print("训练和验证损失接近,训练和验证准确率也接近,过拟合可能性较小。") | |
130 | ||
131 | # 保存预测结果 | |
132 | y_pred = model.predict(X_test) | |
133 | y_pred_classes = np.argmax(y_pred, axis=1) | |
134 | y_pred_classes_adjusted = y_pred_classes + 1 | |
135 | predictions_adjusted = pd.DataFrame({'True': y_test + 1, 'Predicted': y_pred_classes_adjusted}) | |
136 | predictions_adjusted.to_csv('/home/xjy/pythonProject/predictions_solo.csv', index=False) | |
137 | ||
138 | # 打印评价指标 | |
139 | print(classification_report(y_test + 1, y_pred_classes_adjusted)) |