【问题标题】:Correctly preprocess csv data for 1D CNN为 1D CNN 正确预处理 csv 数据
【发布时间】:2020-11-12 11:24:45
【问题描述】:

我在准备数据集以提供 1D CNN 时遇到问题。

我的 CSV 有 3025 个列,代表一个字节 + 最后一个列作为字符串标签。

也许不是预处理的问题,而是在我的网络模型上。

这是我的模型:

def cnn_1d(num_classes):
    model = models.Sequential()
    model.add(Conv1D(16, kernel_size=3, strides=1, activation="relu", input_shape=(3025, 1)))
    model.add(Conv1D(16, kernel_size=3, strides=1, activation="relu"))
    model.add(MaxPooling1D(pool_size=2))
    model.add(Dropout(0.2))
    model.add(Conv1D(32, kernel_size=3, strides=1, activation="relu"))
    model.add(Conv1D(32, kernel_size=3, strides=1, activation="relu"))
    model.add(MaxPooling1D(pool_size=2))
    model.add(Dropout(0.2))
    model.add(Dense(500, activation="relu"))
    model.add(Dense(300, activation="relu"))
    model.add(Dense(num_classes, activation="softmax"))
    model.compile(
        optimizer=keras.optimizers.Adam(1e-3),
        loss="categorical_crossentropy",
        metrics=["accuracy"],
    )
    model.summary()
    return model

这是我尝试预处理数据的方式:

num_classes = 4
df = pd.read_csv("test.csv", header=0)

df["label"] = pd.Categorical(df["label"])
df["label"] = df.label.cat.codes

Y = df.pop("label")
X = df.copy()

x_train, x_test, y_train, y_test = train_test_split(np.asarray(X), np.asarray(Y), test_size=0.33, shuffle=True)

x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))
x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1], 1))

model = cnn_1d(num_classes)
model.fit(x_train, y_train, epochs=100, batch_size=64, validation_data=(x_test, y_test))

我认为由于标签预处理不正确,我在最后一个 Dense 层上遇到了错误。这个我

 ValueError: Shapes (None, 1) and (None, 753, 4) are incompatible

我错过了什么?我所知道的是最后一个 Dense 层应该有 num 个类作为单位计数(在我的示例中为 4)。

【问题讨论】:

    标签: python tensorflow keras conv-neural-network convolution


    【解决方案1】:

    这是您上面提供的代码的模型摘要:

    Model: "sequential_1"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    conv1d (Conv1D)              (None, 3023, 16)          64        
    _________________________________________________________________
    conv1d_1 (Conv1D)            (None, 3021, 16)          784       
    _________________________________________________________________
    max_pooling1d (MaxPooling1D) (None, 1510, 16)          0         
    _________________________________________________________________
    dropout (Dropout)            (None, 1510, 16)          0         
    _________________________________________________________________
    conv1d_2 (Conv1D)            (None, 1508, 32)          1568      
    _________________________________________________________________
    conv1d_3 (Conv1D)            (None, 1506, 32)          3104      
    _________________________________________________________________
    max_pooling1d_1 (MaxPooling1 (None, 753, 32)           0         
    _________________________________________________________________
    dropout_1 (Dropout)          (None, 753, 32)           0         
    _________________________________________________________________
    dense (Dense)                (None, 753, 500)          16500     
    _________________________________________________________________
    dense_1 (Dense)              (None, 753, 300)          150300    
    _________________________________________________________________
    dense_2 (Dense)              (None, 753, 4)            1204      
    =================================================================
    Total params: 173,524
    Trainable params: 173,524
    Non-trainable params: 0
    

    输出层的维度为(批次、序列长度、4 类)。您可能打算在第二个 max_pooling 层之后展平矩阵。

    如果我这样做,我会得到一个参数较少的模型,并将输出 4 个类之一...

    def cnn_1d(num_classes):
        model = models.Sequential()
        model.add(Conv1D(16, kernel_size=3, strides=1, activation="relu", input_shape=(3025, 1)))
        model.add(Conv1D(16, kernel_size=3, strides=1, activation="relu"))
        model.add(MaxPooling1D(pool_size=2))
        model.add(Dropout(0.2))
        model.add(Conv1D(32, kernel_size=3, strides=1, activation="relu"))
        model.add(Conv1D(32, kernel_size=3, strides=1, activation="relu"))
        model.add(MaxPooling1D(pool_size=2))
        model.add(Flatten())
        model.add(Dropout(0.2))
        model.add(Dense(500, activation="relu"))
        model.add(Dense(300, activation="relu"))
        model.add(Dense(num_classes, activation="softmax"))
        model.compile(
            optimizer=keras.optimizers.Adam(1e-3),
            loss="categorical_crossentropy",
            metrics=["accuracy"],
        )
        model.summary()
        return model
      
    cnn_1d(4)
    
    Model: "sequential_2"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    conv1d_4 (Conv1D)            (None, 3023, 16)          64        
    _________________________________________________________________
    conv1d_5 (Conv1D)            (None, 3021, 16)          784       
    _________________________________________________________________
    max_pooling1d_2 (MaxPooling1 (None, 1510, 16)          0         
    _________________________________________________________________
    dropout_2 (Dropout)          (None, 1510, 16)          0         
    _________________________________________________________________
    conv1d_6 (Conv1D)            (None, 1508, 32)          1568      
    _________________________________________________________________
    conv1d_7 (Conv1D)            (None, 1506, 32)          3104      
    _________________________________________________________________
    max_pooling1d_3 (MaxPooling1 (None, 753, 32)           0         
    _________________________________________________________________
    flatten (Flatten)            (None, 24096)             0         
    _________________________________________________________________
    dropout_3 (Dropout)          (None, 24096)             0         
    _________________________________________________________________
    dense_3 (Dense)              (None, 500)               12048500  
    _________________________________________________________________
    dense_4 (Dense)              (None, 300)               150300    
    _________________________________________________________________
    dense_5 (Dense)              (None, 4)                 1204      
    =================================================================
    Total params: 12,205,524
    Trainable params: 12,205,524
    Non-trainable params: 0
    

    作为奖励,此模型的可训练参数显着减少。

    【讨论】:

    • 是的,我发现在最后一个 MaxPool1D 之后我错过了 Flatten 层,我的错误。似乎我也需要在 y_* 变量上强制 to_categorical 才能使用最后一个 Dense 层
    【解决方案2】:

    我知道我错过了什么:

    1. 我错过了对 y_* 变量使用 to_categorical。我认为它已经与df["label"] = pd.Categorical(df["label"]) 分类。所以在模型之前我添加了:
      y_train = to_categorical(y_train, 4)
      y_test = to_categorical(y_test, 4)
      
    2. 我忘记在最后一个 MaxPool1D 层之后展平输出。

    现在它可以正常工作了。

    【讨论】:

      猜你喜欢
      • 2020-09-10
      • 2011-01-25
      • 2020-08-30
      • 1970-01-01
      • 2020-03-30
      • 1970-01-01
      • 1970-01-01
      • 2016-08-05
      • 2018-05-26
      相关资源
      最近更新 更多