CIFAR-10 ไม่สามารถรับความแม่นยำสูงกว่า 60% ได้ Keras พร้อมแบ็กเอนด์ Tensorflow [ปิด]


11

การฝึกอบรมหลังจาก 15 epochs บนชุดข้อมูล CIFAR-10 ดูเหมือนว่าจะทำให้การสูญเสียการตรวจสอบความถูกต้องไม่ลดลงอีกต่อไปโดยประมาณ 1.4 (มีความแม่นยำในการตรวจสอบ 60%) ฉันได้สับชุดฝึกอบรมแล้วหารด้วย 255 และนำเข้าเป็น float32 ฉันได้ลองสถาปัตยกรรมจำนวนมากทั้งที่มีและไม่มีการออกกลางคันในชั้น Conv2D และดูเหมือนว่าจะไม่มีอะไรทำงาน สถาปัตยกรรมเดียวกันมีความแม่นยำถึง 99.7% สำหรับชุดทดสอบสำหรับ MNIST โปรดดูสถาปัตยกรรมด้านล่าง:

(หมายเหตุ: ฉันได้ลองเพิ่มการออกกลางคันและเพิ่ม / ลดอัตราการเรียนรู้ของเครื่องมือเพิ่มประสิทธิภาพ Adam เพื่อป้องกันการ overfitting ทั้งหมดนี้เป็นการป้องกันการ overfitting แต่ด้วยชุดฝึกอบรมและการทดสอบที่มีความแม่นยำต่ำประมาณ 60%)

with tf.device('/gpu:0'):
    tf.placeholder(tf.float32, shape=(None, 20, 64))
    #placeholder initialized (pick /cpu:0 or /gpu:0)
    seed = 6
    np.random.seed(seed)
    modelnn = Sequential()
    neurons = x_train_reduced.shape[1:]

    modelnn.add(Convolution2D(32, 3, 3, input_shape=neurons, activation='relu', border_mode='same'))
    modelnn.add(Convolution2D(32, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(Dropout(0.2))
    modelnn.add(Convolution2D(64, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(Convolution2D(64, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(Dropout(0.2))
    modelnn.add(Convolution2D(128, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(Convolution2D(128, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(Dropout(0.2))
    #modelnn.add(Convolution2D(256, 3, 3, activation='relu', border_mode='same'))
    #modelnn.add(Convolution2D(256, 3, 3, activation='relu', border_mode='same'))
    #modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(Flatten())
    #modelnn.add(Dropout(0.5))
    modelnn.add(Dense(1024, activation='relu', W_constraint=maxnorm(3)))
    modelnn.add(Dropout(0.5))
    modelnn.add(Dense(512, activation='relu', W_constraint=maxnorm(3)))
    modelnn.add(Dropout(0.5))
    modelnn.add(Dense(10, activation='softmax'))
    modelnn.compile(loss='categorical_crossentropy', optimizer=optimizer_input, metrics=['accuracy'])
    y_train = to_categorical(y_train)
    modelnn.fit(x_train_reduced, y_train, nb_epoch=nb_epoch_count, shuffle=True, batch_size=bsize,
                           validation_split=0.1)

ผล:

    44100/44100 [==============================] - 22s - loss: 2.1453 - acc: 0.2010 - val_loss: 1.9812 - val_acc: 0.2959
    Epoch 2/50
    44100/44100 [==============================] - 24s - loss: 1.9486 - acc: 0.3089 - val_loss: 1.8685 - val_acc: 0.3567
    Epoch 3/50
    44100/44100 [==============================] - 18s - loss: 1.8599 - acc: 0.3575 - val_loss: 1.7822 - val_acc: 0.3982
    Epoch 4/50
    44100/44100 [==============================] - 18s - loss: 1.7925 - acc: 0.3933 - val_loss: 1.7272 - val_acc: 0.4229
    Epoch 5/50
    44100/44100 [==============================] - 18s - loss: 1.7425 - acc: 0.4195 - val_loss: 1.6806 - val_acc: 0.4459
    Epoch 6/50
    44100/44100 [==============================] - 18s - loss: 1.6998 - acc: 0.4440 - val_loss: 1.6436 - val_acc: 0.4682
    Epoch 7/50
    44100/44100 [==============================] - 18s - loss: 1.6636 - acc: 0.4603 - val_loss: 1.6156 - val_acc: 0.4837
    Epoch 8/50
    44100/44100 [==============================] - 18s - loss: 1.6333 - acc: 0.4781 - val_loss: 1.6351 - val_acc: 0.4776
    Epoch 9/50
    44100/44100 [==============================] - 18s - loss: 1.6086 - acc: 0.4898 - val_loss: 1.5732 - val_acc: 0.5063
    Epoch 10/50
    44100/44100 [==============================] - 18s - loss: 1.5776 - acc: 0.5065 - val_loss: 1.5411 - val_acc: 0.5227
    Epoch 11/50
    44100/44100 [==============================] - 18s - loss: 1.5585 - acc: 0.5145 - val_loss: 1.5485 - val_acc: 0.5212
    Epoch 12/50
    44100/44100 [==============================] - 18s - loss: 1.5321 - acc: 0.5288 - val_loss: 1.5354 - val_acc: 0.5316
    Epoch 13/50
    44100/44100 [==============================] - 18s - loss: 1.5082 - acc: 0.5402 - val_loss: 1.5022 - val_acc: 0.5427
    Epoch 14/50
    44100/44100 [==============================] - 18s - loss: 1.4945 - acc: 0.5438 - val_loss: 1.4916 - val_acc: 0.5490
    Epoch 15/50
    44100/44100 [==============================] - 192s - loss: 1.4762 - acc: 0.5535 - val_loss: 1.5159 - val_acc: 0.5394
    Epoch 16/50
    44100/44100 [==============================] - 18s - loss: 1.4577 - acc: 0.5620 - val_loss: 1.5389 - val_acc: 0.5257
    Epoch 17/50
    44100/44100 [==============================] - 18s - loss: 1.4425 - acc: 0.5671 - val_loss: 1.4590 - val_acc: 0.5667
    Epoch 18/50
    44100/44100 [==============================] - 18s - loss: 1.4258 - acc: 0.5766 - val_loss: 1.4552 - val_acc: 0.5763
    Epoch 19/50
    44100/44100 [==============================] - 18s - loss: 1.4113 - acc: 0.5805 - val_loss: 1.4439 - val_acc: 0.5767
    Epoch 20/50
    44100/44100 [==============================] - 18s - loss: 1.3971 - acc: 0.5879 - val_loss: 1.4473 - val_acc: 0.5769
    Epoch 21/50
    44100/44100 [==============================] - 18s - loss: 1.3850 - acc: 0.5919 - val_loss: 1.4251 - val_acc: 0.5871
    Epoch 22/50
    44100/44100 [==============================] - 18s - loss: 1.3668 - acc: 0.6006 - val_loss: 1.4203 - val_acc: 0.5910
    Epoch 23/50
    44100/44100 [==============================] - 18s - loss: 1.3549 - acc: 0.6051 - val_loss: 1.4207 - val_acc: 0.5939
    Epoch 24/50
    44100/44100 [==============================] - 18s - loss: 1.3373 - acc: 0.6111 - val_loss: 1.4516 - val_acc: 0.5784
    Epoch 25/50
    44100/44100 [==============================] - 18s - loss: 1.3285 - acc: 0.6149 - val_loss: 1.4146 - val_acc: 0.5922
    Epoch 26/50
    44100/44100 [==============================] - 18s - loss: 1.3134 - acc: 0.6205 - val_loss: 1.4090 - val_acc: 0.6024
    Epoch 27/50
    44100/44100 [==============================] - 18s - loss: 1.3043 - acc: 0.6239 - val_loss: 1.4307 - val_acc: 0.5959
    Epoch 28/50
    44100/44100 [==============================] - 18s - loss: 1.2862 - acc: 0.6297 - val_loss: 1.4241 - val_acc: 0.5978
    Epoch 29/50
    44100/44100 [==============================] - 18s - loss: 1.2706 - acc: 0.6340 - val_loss: 1.4046 - val_acc: 0.6067
    Epoch 30/50
    44100/44100 [==============================] - 18s - loss: 1.2634 - acc: 0.6405 - val_loss: 1.4120 - val_acc: 0.6037
    Epoch 31/50
    44100/44100 [==============================] - 18s - loss: 1.2473 - acc: 0.6446 - val_loss: 1.4067 - val_acc: 0.6045
    Epoch 32/50
    44100/44100 [==============================] - 18s - loss: 1.2411 - acc: 0.6471 - val_loss: 1.4083 - val_acc: 0.6098
    Epoch 33/50
    44100/44100 [==============================] - 18s - loss: 1.2241 - acc: 0.6498 - val_loss: 1.4091 - val_acc: 0.6076
    Epoch 34/50
    44100/44100 [==============================] - 18s - loss: 1.2121 - acc: 0.6541 - val_loss: 1.4209 - val_acc: 0.6127
    Epoch 35/50
    44100/44100 [==============================] - 18s - loss: 1.1995 - acc: 0.6582 - val_loss: 1.4230 - val_acc: 0.6131
    Epoch 36/50
    44100/44100 [==============================] - 18s - loss: 1.1884 - acc: 0.6622 - val_loss: 1.4024 - val_acc: 0.6124
    Epoch 37/50
    44100/44100 [==============================] - 18s - loss: 1.1778 - acc: 0.6657 - val_loss: 1.4328 - val_acc: 0.6080
    Epoch 38/50
    44100/44100 [==============================] - 18s - loss: 1.1612 - acc: 0.6683 - val_loss: 1.4246 - val_acc: 0.6159
    Epoch 39/50
    44100/44100 [==============================] - 18s - loss: 1.1466 - acc: 0.6735 - val_loss: 1.4282 - val_acc: 0.6122
    Epoch 40/50
    44100/44100 [==============================] - 18s - loss: 1.1325 - acc: 0.6783 - val_loss: 1.4311 - val_acc: 0.6157
    Epoch 41/50
    44100/44100 [==============================] - 18s - loss: 1.1213 - acc: 0.6806 - val_loss: 1.4647 - val_acc: 0.6047
    Epoch 42/50
    44100/44100 [==============================] - 18s - loss: 1.1064 - acc: 0.6842 - val_loss: 1.4631 - val_acc: 0.6047
    Epoch 43/50
    44100/44100 [==============================] - 18s - loss: 1.0967 - acc: 0.6870 - val_loss: 1.4535 - val_acc: 0.6106
    Epoch 44/50
    44100/44100 [==============================] - 18s - loss: 1.0822 - acc: 0.6893 - val_loss: 1.4532 - val_acc: 0.6149
    Epoch 45/50
    44100/44100 [==============================] - 18s - loss: 1.0659 - acc: 0.6941 - val_loss: 1.4691 - val_acc: 0.6108
    Epoch 46/50
    44100/44100 [==============================] - 18s - loss: 1.0610 - acc: 0.6956 - val_loss: 1.4751 - val_acc: 0.6106
    Epoch 47/50
    44100/44100 [==============================] - 18s - loss: 1.0397 - acc: 0.6981 - val_loss: 1.4857 - val_acc: 0.6041
    Epoch 48/50
    44100/44100 [==============================] - 18s - loss: 1.0208 - acc: 0.7039 - val_loss: 1.4901 - val_acc: 0.6106
    Epoch 49/50
    44100/44100 [==============================] - 18s - loss: 1.0187 - acc: 0.7036 - val_loss: 1.4994 - val_acc: 0.6106
    Epoch 50/50
    44100/44100 [==============================] - 18s - loss: 1.0024 - acc: 0.7070 - val_loss: 1.5078 - val_acc: 0.6039
    Time: 1109.7512991428375
    Neural Network now trained from dimensions (49000, 3, 32, 32)

อัปเดต: การทดสอบเพิ่มเติมรวมถึง BatchNormalization ทั้งที่มีและไม่มี MaxNorm -

img

สถาปัตยกรรมใหม่:

    modelnn.add(Convolution2D(32, 3, 3, input_shape=neurons, activation='relu', border_mode='same'))
    modelnn.add(Convolution2D(32, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(BatchNormalization())
    modelnn.add(Dropout(0.2))
    modelnn.add(Convolution2D(64, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(Convolution2D(64, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(BatchNormalization())
    modelnn.add(Dropout(0.2))
    modelnn.add(Convolution2D(128, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(Convolution2D(128, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(BatchNormalization())
    modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(Dropout(0.2))
    # modelnn.add(Convolution2D(256, 3, 3, activation='relu', border_mode='same'))
    # modelnn.add(Convolution2D(256, 3, 3, activation='relu', border_mode='same'))
    # modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(Flatten())
    modelnn.add(Dense(1024, activation='relu', W_constraint=maxnorm(3)))
    modelnn.add(BatchNormalization())
    modelnn.add(Dropout(0.5))
    modelnn.add(Dense(512, activation='relu', W_constraint=maxnorm(3)))
    modelnn.add(BatchNormalization())
    modelnn.add(Dropout(0.5))
    modelnn.add(Dense(10, activation='softmax'))

คำตอบ:


8

โปรดทราบว่า MNIST เป็นชุดปัญหาที่ง่ายกว่า CIFAR-10 มากและคุณสามารถรับ 98% จาก NNet ที่ไม่ได้เชื่อมต่อแบบเต็มรูปแบบ ซีเอ็นเอ็นง่าย ๆ ที่มีเลเยอร์ convolutional เพียงหนึ่งหรือสองเลเวลก็สามารถได้รับความแม่นยำในระดับเดียวกัน

ฉันไม่แน่ใจเกี่ยวกับสถาปัตยกรรม NNet ของคุณ แต่ฉันสามารถนำคุณไปสู่ความแม่นยำในการทดสอบ 78% สำหรับ CIFAR-10 ด้วยสถาปัตยกรรมต่อไปนี้ (ซึ่งค่อนข้างง่ายกว่าและมีน้ำหนักน้อยกว่า) ไม่จำเป็นต้องมีการเริ่มต้นหรือการจัดการเป็นพิเศษโดยใช้ค่าเริ่มต้นของวานิลลาและเครื่องมือเพิ่มประสิทธิภาพของอดัม:

model = Sequential()
model.add(Conv2D(input_shape=trainX[0,:,:,:].shape, filters=96, kernel_size=(3,3)))
model.add(Activation('relu'))
model.add(Conv2D(filters=96, kernel_size=(3,3), strides=2))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Conv2D(filters=192, kernel_size=(3,3)))
model.add(Activation('relu'))
model.add(Conv2D(filters=192, kernel_size=(3,3), strides=2))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(BatchNormalization())
model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dense(n_classes, activation="softmax"))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

สถาปัตยกรรมนี้สวยเรียบง่ายและเป็นไปตามอย่างอิสระบนhttps://arxiv.org/pdf/1412.6806.pdf

ฝึกอบรมโมเดลนี้:

n_epochs = 25
batch_size = 256
callbacks_list = None
H = model.fit(trainX, trainY, validation_data=(testX, testY), 
              epochs=n_epochs, batch_size=batch_size, callbacks=callbacks_list)
print('Done!!!')

ให้สิ่งต่อไปนี้ซึ่งคุณสามารถเห็นได้ถึง 77% ในยุคที่ 25 และแบนมากขึ้นหรือน้อยลงจากที่นั่น (แต่มีการทำให้เป็นปกติมากพอสำหรับการออกกลางคันเพื่อป้องกันไม่ให้เกิดการย่อยสลายเนื่องจากการ overfitting อย่างน้อยมากกว่าจำนวนการทดสอบซ้ำ) .

ฝึกฝนตัวอย่าง 50,000 ตัวอย่างตรวจสอบตัวอย่าง 10,000 ตอน
1/50
50000/50000 [==============================] - 19s 390us / ขั้นตอน - การสูญเสีย: 1.6058 - ACC: 0.4150 - val_loss: 1.5285 - val_acc: 0.4669
Epoch 2/50
50000/50000 [======================= =======] - 19s 371us / ขั้นตอน - การสูญเสีย: 1.2563 - acc: 0.5477 - val_loss: 1.1447 - val_acc: 0.5901
Epoch 3/50
50000/50000 [============= =================] - 19s 373us / ขั้นตอน - การสูญเสีย: 1.0784 - ACC: 0.6163 - val_loss: 1.1577 - val_acc: 0.6002
...
ยุค 25/50
50000/50000 [ ==============================] - 19s 374us / ขั้นตอน - การสูญเสีย: 0.3188 - ACC: 0.8857 - val_loss: 0.7493 - val_acc : 0.7680
...
ยุค 50/50
50000/50000 [==============================] - 19s 373us / ขั้นตอน - การสูญเสีย: 0.1928 - acc: 0.9329 - val_loss : 0.8718 - val_acc: 0.7751
เสร็จสิ้น !!!

นี่คือสถาปัตยกรรมที่เรียบง่ายกว่าและเล็กกว่ามากซึ่งสามารถรับ 70% ได้อย่างรวดเร็วด้วยระบบการฝึกอบรมเดียวกัน (ไม่มี BatchNormalization

# CNN architecture with Keras
model = Sequential()
model.add(Conv2D(input_shape=trainX[0,:,:,:].shape, filters=32, 
                 use_bias=True, kernel_size=(3,3)))
model.add(Activation('relu'))
model.add(Dropout(0.1))
model.add(Conv2D(filters=64, use_bias=False, kernel_size=(5,5), strides=2))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.3))
model.add(Dense(n_classes, activation="softmax"))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=    ['accuracy'])

เป็นที่น่าสังเกตว่าสถาปัตยกรรมที่ได้รับการเผยแพร่อย่างแม่นยำที่สุดใน CIFAR-10 (ปัจจุบันอยู่ในช่วง 90-96%) นั้นซับซ้อนกว่าและใช้เวลาในการฝึกฝนฮาร์ดแวร์ GPU แต่ฉันสามารถเข้าถึงช่วง 70-80% ด้วยสถาปัตยกรรมที่ค่อนข้างง่ายซึ่งฝึกฝนในเวลาไม่กี่นาทีซึ่งเป็นสิ่งที่ฉันแนะนำก่อนที่จะได้ผลลัพธ์ที่ดีที่สุดซึ่งมักต้องใช้สถาปัตยกรรมที่ซับซ้อนกว่าระยะเวลาการฝึกอบรมที่ยาวนานขึ้น บางครั้งการจัดการ / การฝึกอบรมพิเศษหรือการเสริมข้อมูลและชั่วโมงการใช้งานของรถไฟ

UPDATE:

ปัญหาที่เห็นได้ชัดที่สุดที่แสดงให้เห็นก็คือการ overfitting ตามการปรับปรุงแปลงในคำถาม นี่คือหลักฐานที่แตกต่างจากข้อมูลการทดสอบรถไฟหลังจากเกี่ยวกับยุคที่ 15 ซึ่งแสดงให้เห็นถึงการทำให้เป็นปกติไม่เพียงพอสำหรับสถาปัตยกรรมนี้สำหรับชุดข้อมูลนี้ คุณจะไม่ได้รับการปรับปรุงจากการปรับพารามิเตอร์ไฮเปอร์พารามิเตอร์อื่น ๆ (กลยุทธ์การทำให้เป็นมาตรฐาน, อัตราการเรียนรู้และอื่น ๆ ) เว้นแต่จะได้รับการแก้ไขมากเกินไป

ในการใช้ NNets ฉันแนะนำต่อไปนี้:

  1. เริ่มต้นจากสถาปัตยกรรมที่เลียนแบบหรือจำลองที่รู้จักกันเพื่อสร้างผลลัพธ์ที่ดี
  2. ตรวจสอบประสิทธิภาพของชุดข้อมูลของคุณโดยเฉพาะอย่างยิ่งการปรับให้เหมาะสมในเครือข่าย (เห็นได้จากความแตกต่างที่สำคัญของข้อผิดพลาดในการทดสอบรถไฟ)
  3. เพิ่มการทำให้เป็นมาตรฐานเพิ่มเติม (เพิ่มอัตราการออกกลางคัน) เมื่อมีการปฏิบัติตาม overfitting (คุณกำลังมองหา "เพียงพอ" เพื่อป้องกันการ overfitting - มากเกินไปจะทำให้ไม่เหมาะสม)
  4. การทดสอบกับโครงสร้างแนวทางการฝึกอบรมและพารามิเตอร์แบบไฮเปอร์เพื่อค้นหาลู่ทางการปรับปรุง

การกำหนดใบสั่งเกี่ยวกับอันที่จริงแล้วค่อนข้างยากที่จะเกิดขึ้นเพราะมีรากฐานทางทฤษฎีเพียงเล็กน้อยสำหรับโครงสร้างการฝึกอบรมหรือพารามิเตอร์ไฮเปอร์ที่มีการโต้ตอบเพื่อให้ได้ประสิทธิภาพในชุดข้อมูลใดก็ตาม การที่วิธีการที่ใช้โดยสถาปัตยกรรมที่ตีพิมพ์ได้รับประสิทธิภาพระดับสูงในระดับเดียวกันในชุดข้อมูลมาตรฐานแตกต่างกันอย่างมากดังนั้นจึงเป็นหลักฐานของสิ่งนี้

Batchnormalization พบว่ามีนัยสำคัญในการปรับปรุงสถาปัตยกรรมบางอย่าง แต่ผู้อื่นสามารถทำได้ค่อนข้างดีหากไม่มีมัน (หรือไม่สนใจสถานะของมัน) คำแนะนำที่แท้จริงเพียงอย่างเดียวที่จะให้ที่นี่คือการลองและดูว่ามีประโยชน์หรือไม่

โดยทั่วไปแล้วควรหลีกเลี่ยงการปรับอัตราการเรียนรู้อย่างละเอียดเว้นแต่ว่าคุณเป็นผู้ประกอบการขั้นสูงที่มีความเข้าใจอย่างลึกซึ้งเกี่ยวกับ ConvNets และความสามารถในการอ่านใบชาที่เกี่ยวข้องกับประสิทธิภาพการทำงานที่เพิ่มขึ้นระหว่างสมัยในระหว่างการฝึกอบรม อัตราการเรียนรู้ที่กำหนดเองและสูตรการฝึกอบรมพิเศษอื่น ๆ ในบางกรณีสามารถช่วยให้เครือข่ายนำทางรอบ ๆ minima ท้องถิ่นและค้นหาวิธีแก้ปัญหาโดยรวมที่ดีกว่า แต่ถ้าคุณไม่มีเวลามากและความรู้ในการวินิจฉัยพฤติกรรมการบรรจบกันของเครือข่าย เป็นจุดเริ่มต้นที่ดี พวกเราส่วนใหญ่ควรใช้เครื่องมือเพิ่มประสิทธิภาพเช่นอดัมซึ่งจะมีประสิทธิภาพสูงกว่าความพยายามสามเณรในอัตราการเรียนรู้ที่ปรับด้วยมือในกรณีส่วนใหญ่

เสริมข้อมูลผ่าน preprocessing ภาพบางครั้งสามารถให้ผลผลิตปรับปรุงประสิทธิภาพการทำงานอย่างมีนัยสำคัญ (โดยทั่วไปที่แตกต่างกันมากขึ้นการป้อนข้อมูลที่ดีกว่ารูปแบบจะคุย - preprocessing ข้อมูลเพิ่มรูปแบบที่จะเข้าพื้นที่ที่สามารถปรับปรุงออกจากกลุ่มตัวอย่างที่ถูกต้องและอาจสามารถลดความต้องการในการทำให้เป็นมาตรฐานได้ - ด้วยสมมติฐานด้วยข้อมูลการฝึกอบรมที่ไม่มีที่สิ้นสุดเราไม่ต้องการการทำให้เป็นมาตรฐานเลย แต่ในพื้นที่การประมวลผลภาพเราไม่น่าจะเข้าใกล้เส้นกำกับนั้นได้ สิ่งนี้สามารถเพิ่มเวลาการฝึกอบรมและอัตราการคอนเวอร์เจนซ์ที่ช้าลงอย่างมีนัยสำคัญและแนะนำชุดพารามิเตอร์ไฮเปอร์พารามิเตอร์อื่น ๆ ที่เกี่ยวข้องกับเทคนิคการเปลี่ยนรูปของภาพอินพุท (การหมุนการครอบตัดการปรับขนาดเสียง ฯลฯ ) เนื่องจากเส้นทางนี้สามารถเพิ่มเวลาการฝึกอบรมและจำเป็นต้องมีการทดสอบเพิ่มเติมเพื่อปรับแต่งผลลัพธ์คำแนะนำทั่วไปบางอย่างก็คือการขับรถเพื่อความแม่นยำที่ดีที่สุดในเครือข่ายของคุณโดยไม่ต้องทำการเสริมก่อนจากนั้นดูว่า หากเป็นเช่นนั้นอาจรับประกันการทดลองเพิ่มเติม

สำหรับการทดลองปรับแต่งใด ๆ และทุกอย่างคุณจะต้องจับตาดูการเปลี่ยนแปลงในพฤติกรรมที่มากเกินไปและไม่เหมาะสม การเปลี่ยนสถาปัตยกรรมเครือข่าย, สูตรการฝึกอบรมหรือพารามิเตอร์หลายมิติอาจต้องการการปรับเพิ่มเติมของการทำให้เป็นมาตรฐานการออกกลางคัน ความสามารถในการตรวจสอบให้แน่ใจว่าพฤติกรรมที่เกินและไม่เหมาะสมจากการฝึกอบรม / การทดสอบนั้นเป็นทักษะพื้นฐานที่สำคัญที่สุดในการทำงานกับ NNets และสิ่งนี้จะกลายเป็นความเข้าใจได้ง่ายขึ้นด้วยประสบการณ์

นี่คือเทียนที่ความพยายามทั้งหมดของคุณจะได้รับการนำทาง เทียนสามารถทำให้แสงสว่างส่องทางเท่านั้น แต่หากไม่มีคุณจะสะดุดในความมืด หากเครือข่ายของคุณไม่เหมาะสมหรือมีขนาดไม่เหมาะสมควรได้รับการแก้ไขก่อนที่จะพยายามเปลี่ยนลำดับโครงสร้างเครือข่ายหรือพารามิเตอร์หลายมิติแบบสุ่ม

สถาปัตยกรรมที่เรียบง่ายเปรียบเทียบกับสูตรการฝึกวานิลลาที่รวมอยู่ในคำตอบนี้แสดงให้เห็นถึงความเป็นจริงของการทำงานกับสถาปัตยกรรม NNET เกี่ยวกับปัญหาที่ยากลำบากเช่นการจำแนกภาพ: การได้ผลลัพธ์ที่ "ดีมาก" ตามวิธีการที่ใช้งานได้ดีไม่ใช่เรื่องยาก มีราคาแพงมากขึ้น การบรรลุผลลัพธ์ที่ดีที่สุดที่เผยแพร่ผ่านการทดลองจะเกินความสามารถหรือเวลาที่มีอยู่ของคนจำนวนมาก (แม้ว่าจะเป็นไปได้มีเวลาและความพยายามมากพอที่จะทำตามสูตรตำราของวิธีการเผยแพร่เพื่อทำซ้ำผลลัพธ์ของพวกเขา หมายถึงไม่สำคัญ) การได้รับการปรับปรุงที่เพิ่มขึ้นจากจุดเริ่มต้น "ดีมาก" อาจเป็นกระบวนการที่ใช้เวลาในการลองผิดลองถูกและใช้เวลามากและการทดลองจำนวนมากจะไม่ทำให้เกิดการปรับปรุงที่สำคัญ

นี่ไม่ได้หมายถึงการห้ามปรามใครก็ตามจากการพยายามเรียนรู้ แต่เพื่อให้ชัดเจนว่ามีการลงทุนที่สำคัญที่จำเป็นต้องมีต้นแบบชุดเครื่องมือ (เคยมีการขยาย) ในกระเป๋าของ NNet และการปรับปรุงการขับรถผ่านการลองผิดลองถูก การทดลองหลายสิบ (หรือหลายร้อย) การทดลองในช่วงวันหรือสัปดาห์ของการฝึกอบรมเฉพาะ GPU

เวลาทักษะและทรัพยากร (GPU เฉพาะ) จำเป็นต้องใช้ในการฝึกอบรมเครือข่ายให้มีประสิทธิภาพระดับสูงมากซึ่งเป็นส่วนหนึ่งของความนิยมของเครือข่ายที่ได้รับการฝึกฝนมาก่อน


1
สถาปัตยกรรมเครือข่ายประสาทคุณไม่มีเลเยอร์รวมกันหรือไม่ ไม่สร้างจำนวนพารามิเตอร์ที่ไม่สามารถจัดการได้ใช่ไหม
Spandyie

2
การรวม - pfft! overrated วิธีนี้ใช้วิธีการแบบ all-convolutional ซึ่งใช้ striding สำหรับการทำลายล้างมากกว่าการรวมกำไร - ดูเอกสารที่เชื่อมโยงเพื่อดูคำอธิบาย การก้าวเข้าสู่ Convolutional สามารถรับผล "funneling" แบบเดียวกับการรวมกำไรโดยใช้วิธีที่ต่างกันเล็กน้อย พวกเขาทั้งสองทำงานเพียงแค่แสดงให้เห็นว่าไม่มีเหตุผลทางทฤษฎีมากมายที่จะยืนหยัดได้ว่าทำไมสิ่งเหล่านี้ถึงได้ผล
T3am5hark

6

ดูค่าการสูญเสียและความแม่นยำในตัวอย่างและนอกตัวอย่างของคุณรุ่นของคุณอยู่ภายใต้การติดตั้ง แต่มันก็ปรับปรุงให้น่าเบื่อ กล่าวอีกนัยหนึ่งดูเหมือนว่าการใช้สิ่งนี้เพื่อยุคที่มากขึ้นจะส่งผลให้ประสิทธิภาพการทำนายสูงขึ้น / การสูญเสียพลังงานแบบเอนโทรปีน้อยลง

คุณกำลังใช้สถาปัตยกรรม (เลเยอร์แบบเลื่อนลง) ที่ปรับมาตรฐานซึ่งไม่เลว อย่างไรก็ตามก็ไม่น่าแปลกใจที่การฝึกอบรมใช้เวลานานกว่าปกติมาก เนื่องจากเลเยอร์แบบเลื่อนออกไม่น่าเป็นไปได้ที่คุณจะมีความเหมาะสม (อย่างมาก)

สิ่งที่คุณสามารถพยายามเร่งการเรียนรู้:

ผม. ปรับอัตราการเรียนรู้: เช่นเริ่มจากตัวเล็ก ๆ ยกขึ้นตรงกลางแล้วค่อยๆลดลงอีกครั้ง

ii เพิ่มbatchnormalisation : ในสถาปัตยกรรมด้านบนคุณสามารถรวม batch-norm ทั้งในบล็อกของคุณและเลเยอร์หนาแน่น โดยปกติเลเยอร์ชุดค่าเริ่มต้นจะถูกเพิ่มหลังจากการเปิดใช้งานแบบไม่เชิงเส้น แต่ก่อนออกกลางคัน ฉันไม่แน่ใจว่าชุดคำสั่งชุดเล่นกับ maxnorm ได้ดีแค่ไหน สำหรับเลเยอร์ที่หนาแน่นของคุณฉันจะลอง batch-norm + dropuout โดยมี / ไม่มี maxnorm ฉันมีความรู้สึกว่าคุณไม่จำเป็นต้องใช้ maxnorm ถ้าคุณใช้การทำให้เป็นมาตรฐานแบบกลุ่ม

สาม. เพิ่มขนาดแบทช์: ฉันไม่แน่ใจว่าขนาดแบทช์ของคุณคืออะไรและคุณเป็นเจ้าของ GPU หรือไม่ หากคุณมี GPU คุณอาจลองเพิ่มขนาดชุดของคุณเป็น 32 คูณ

ในที่สุดเพื่อให้แน่ใจว่าข้อมูลของคุณ 'เรียนรู้ได้' / ไม่เสียหาย (เช่นคุณไม่ได้ใช้การแปลงเพื่อแปรปรวนอย่างไม่เต็มใจ) ฉันจะทิ้งการทำให้เป็นปกติทั้งหมดจากสถาปัตยกรรมของคุณทำการฝึกอบรมและดูว่าคุณสามารถ . หากคุณสามารถเรียนรู้ข้อมูลการฝึกอบรมได้สำเร็จส่วนที่เหลือเป็นแบบฝึกหัดทั่วไป หากคุณไม่สามารถฝึกอบรมข้อมูลได้มากเกินไปแม้ว่าจะไม่มีการทำให้เป็นปกติก็เป็นไปได้ว่าโมเดลของคุณต้องการความจุมากขึ้น (สถาปัตยกรรมที่ลึกกว่าและกว้างกว่า)


ขอบคุณสำหรับคำแนะนำ! คุณพูดถูกเกี่ยวกับ MaxNorm เล็กน้อย อย่างไรก็ตามแม้หลังจากเพิ่มเลเยอร์ BatchNormalization (โปรดดูอัปเดต) และทั้งการลบ / รวม MaxNorm ความแม่นยำยังอยู่ในระดับต่ำ ไม่มีการเสริมกำลังเช่นกัน ฉันมี GPU และได้ลองการฝึกอบรมที่ 64,128,256 และ 512 แบทช์ แต่สังเกตเห็นความแตกต่างเล็กน้อย เกี่ยวกับอัตราการเรียนรู้ฉันใช้เครื่องมือเพิ่มประสิทธิภาพของอดัมและคิดว่าควรเหลือไว้เพียงอย่างเดียวหรือไม่ ฉันไม่เคยลอง LR ที่ 0.05, 0.001, 0.0005 และสังเกตว่าค่าเริ่มต้น 0.001 ยังคงดีที่สุด ความคิดใด ๆ
user4779

นอกจากนี้ฉันยังสามารถทนได้ดี ฉันพยายามอย่างดีที่สุดเพื่อคัดลอกสถาปัตยกรรมในเอกสารที่ดูเหมือนว่าจะสามารถบรรลุความแม่นยำ 80% ++ ด้วย MNIST10 เมื่อฉันออกจากการฝึกอบรมแบบจำลองสำหรับยุคที่ยาวขึ้นดูเหมือนว่าการสูญเสียจะเพิ่มขึ้น (มากกว่า 20 ยุคขึ้นไป)
user4779

ความคิดเห็นที่ปรับเปลี่ยน - หลังจากการเปลี่ยนแปลงตัวแบบกราฟตอนนี้แสดงให้เห็นว่ามันเป็นข้อมูลที่มีนัยสำคัญมากเกินไป (ขึ้นอยู่กับความคลาดเคลื่อนของข้อผิดพลาดในการตรวจสอบความถูกต้องหลังจาก ~ 15 epochs)
T3am5hark

จริง ๆ แล้วฉันโต้แย้งข้อเสนอของยูทิลิตี้ที่เสนอที่นี่โดยเฉพาะอย่างยิ่งสำหรับผู้ปฏิบัติงานใหม่ นี่คือทุกสิ่งที่คุณสามารถทำได้แน่นอน แต่สำหรับคนที่ยังใหม่กับ CNN และไม่มีสัญชาตญาณหรือความเข้าใจในการทำงานของสิ่งเหล่านี้มันเป็นลูกบิดและคันโยกมากเกินไปที่จะปรับแต่งโดยไม่มีคำแนะนำที่กำหนดล่วงหน้าอื่น ๆ และข้อผิดพลาดไม่น่าจะให้ผลลัพธ์ที่เป็นบวก ดีกว่าเริ่มแรกด้วยสถาปัตยกรรมที่เรียบง่ายกว่าที่สามารถรับประสิทธิภาพที่ดี (ไม่ได้รับการตีพิมพ์ที่ดีที่สุด) โดยมีการเล่นสองครั้งน้อยที่สุดจากนั้นสำรวจเส้นทางการปรับปรุงจากที่นั่น สองเซ็นต์ของฉัน
T3am5hark

หากต้องการรายละเอียดเพิ่มเติม - อย่าเล่นกับอัตราการเรียนรู้ให้ใช้อดัม มันจะเอาชนะการปรับอัตราการเรียนรู้ด้วยมือ 99.99% ของเวลา นอกจากนี้คำแถลงว่า "ไม่น่าเป็นไปได้ที่คุณจะเกินความคาดหมาย" เป็นเพียงข้อผิดพลาดธรรมดา (ตามที่ระบุโดยกราฟิกติดตามผลซึ่งตอนนี้แสดงให้เห็นถึงการปรับตัวที่สำคัญเกินไป) และไม่มีเหตุผลที่ดีสำหรับผู้โปสเตอร์ ไม่มีอะไรจะบอกให้คุณทราบล่วงหน้าเกี่ยวกับสถาปัตยกรรมที่กำหนดว่าอัตราการออกกลางคันที่กำหนดจะเพียงพออย่างสม่ำเสมอเพื่อป้องกันการปรับตัวที่มากเกินไป
T3am5hark

1

ฉันให้ภาพนี้ในวันนี้และสามารถยิงได้แม่นยำเกือบ 75-80% ในการทดสอบ

ประวัติการฝึกอบรม

  • จำนวนพารามิเตอร์ทั้งหมดที่ใช้คือ: 183,242

  • คุณสามารถทำได้ดีกว่าด้วยการเพิ่มเลเยอร์อีกสองสามตัว แต่คุณไม่จำเป็นต้องมากเกินไป เครือข่ายที่ซับซ้อนมากขึ้นอาจไม่ได้ผลลัพธ์ที่ดีกว่าเสมอไป

ข้อเสนอแนะ

ข้อเสนอแนะของฉันสำหรับคุณคือคุณทำให้สถาปัตยกรรมของคุณง่ายขึ้น ติดตามมีดโกนของอ็อกคัมง่ายกว่าดีกว่า

  • ปรับขนาดข้อมูลของคุณ

  • อย่าใช้เมล็ดสุ่ม

  • ใช้เครื่องมือเพิ่มประสิทธิภาพที่เหมาะสม ฉันใช้ Adadelta จาก Keras

  • ซีเอ็นเอ็นไม่จำเป็นต้องมีความซับซ้อน; ง่าย ๆ เข้าไว้

  • เครือข่ายที่ลึกกว่าบางครั้งก็ทำงานได้ดีกว่าเครือข่ายที่กว้างกว่า

  • ใช้การทำให้เป็นมาตรฐาน (เช่น Dropout)

ด้านล่างเป็นรหัสของฉัน (ใช้ Keras)

# Define the model
model = Sequential()
model.add(Convolution2D(64, (4, 4), padding='same', input_shape=(3, 32, 32)))
model.add(MaxPooling2D(pool_size=(2, 2), strides=2))
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Convolution2D(64, (2, 2), padding='same'))
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Convolution2D(32, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Convolution2D(32, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=2))
model.add(Dropout(0.15))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Dense(64))
model.add(Activation('tanh'))
model.add(Dropout(0.25))
model.add(Dense(num_classes, activation='softmax'))
# Compile the model
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.