Pendekatan pembelajaran mendalam multi-model untuk pemahaman gambar dan teks

Dengan kemajuan “pembelajaran mendalam” seperti “jaringan saraf konvolusional” (yaitu, “ConvNet”) [1], “visi komputer” kembali menjadi topik penelitian ilmiah yang hangat. Salah satu tujuan utama visi komputer saat ini adalah menggunakan pembelajaran mesin (terutama pembelajaran mendalam) untuk melatih komputer agar memperoleh pemahaman tingkat manusia dari gambar digital, teks, atau video.

Dengan penggunaannya yang luas, ConvNet menjadi model de facto untuk pengenalan gambar. Seperti yang dijelaskan dalam [1], secara umum, ada dua pendekatan untuk menggunakan ConvNet untuk computer vision:

  • Melatih model ConvNet baru dari awal
  • Menggunakan pembelajaran transfer, yaitu menggunakan model ConvNet yang telah dilatih sebelumnya

Seperti yang ditunjukkan dalam diagram berikut, model ConvNet terdiri dari dua bagian: basis konvolusional dan pengklasifikasi yang terhubung sepenuhnya.

Gambar 1:Skenario umum pembelajaran transfer ConvNet.

Pembelajaran transfer ConvNet dapat dibagi lagi menjadi tiga metode:

  • Metode 1: Ekstraksi fitur tanpa argumentasi gambar [1]
    Metode ini menggunakan basis konvolusional terlatih untuk mengonversi gambar baru menjadi array seperti array Numpy (dapat disimpan ke dalam file jika diperlukan ) terlebih dahulu dan kemudian gunakan representasi array gambar dalam memori untuk melatih model klasifikasi baru yang terpisah dengan bobot yang diinisialisasi secara acak.
  • Metode 2: Ekstraksi fitur dengan argumentasi gambar [1]
    Metode ini membangun model baru dengan basis konvolusional terlatih sebagai lapisan masukan, membekukan bobot basis konvolusional, dan terakhir menambahkan pengklasifikasi keluaran baru dengan bobot yang diinisialisasi secara acak.
  • Metode 3: Penyempurnaan [1]
    Metode ini tidak menggunakan seluruh basis konvolusional yang telah dilatih sebelumnya dan dibekukan. Hal ini memungkinkan untuk mencairkan beberapa lapisan atas dari basis konvolusional yang telah dilatih sebelumnya yang telah dibekukan sehingga lapisan atas yang telah dicairkan tersebut dapat dilatih bersama dengan pengklasifikasi baru yang terhubung sepenuhnya.

Metode 2 digunakan dalam artikel ini untuk pembelajaran transfer model multi-input.

Ide utama di balik pembelajaran transfer dapat digunakan tidak hanya untuk ConvNet yang diawasi tetapi juga algoritma pembelajaran mendalam lainnya seperti model penyematan kata tanpa pengawasan untuk pemrosesan bahasa alami (NLP)[4].

Ada dua model penyematan kata terlatih yang populer: word2vec dan GloVe [3]. Seperti model word2vec-keras yang digunakan dalam [4], model penyematan kata terlatih ini biasanya digabungkan dengan algoritme pembelajaran mendalam terawasi lainnya seperti jaringan saraf berulang (RNN) LSTM untuk NLP seperti klasifikasi teks [4].

Model ConvNet atau model NLP (misalnya kombinasi penyematan kata dengan LSTM) dapat digunakan secara terpisah untuk memecahkan banyak masalah menarik dalam computer vision dan NLP. Seperti yang akan ditunjukkan dalam artikel ini, berbagai jenis model ini juga dapat digabungkan dengan berbagai cara [1] untuk membentuk model yang lebih kuat guna mengatasi masalah yang lebih menantang seperti otomatisasi proses klaim asuransi yang tidak hanya memerlukan kemampuan pengenalan gambar tetapi juga pemahaman bahasa alami (misalnya teks).

Artikel ini menggunakan kumpulan data yang menarik namun menantang di Kaggle, “Tantangan dalam Pembelajaran Representasi: Pembelajaran Multi-modal” [2], untuk menyajikan model pembelajaran transfer multi-input baru yang menggabungkan dua model input dengan lapisan klasifikasi yang terhubung sepenuhnya untuk keduanya. pengenalan gambar dan pengenalan tag kata secara bersamaan (lihat Gambar 2).

Ide utama di balik model multi-input baru ini adalah untuk menerjemahkan masalah pengenalan tag gambar dan kata ke dalam masalah klasifikasi pembelajaran mesin, yaitu menentukan apakah gambar tertentu cocok dengan kumpulan tag kata tertentu (0-Tidak, 1-Ya).

1. Persiapan Data

Setelah kumpulan data Kaggle dari file gambar dan file tag kata [2] diunduh ke mesin lokal, kode di bawah ini dapat digunakan untuk membuat dan mengacak daftar nama file gambar dan nama file tag kata terkait. Ada 100.000 file gambar dan 100.000 file tag kata yang sesuai dalam kumpulan data untuk tujuan pelatihan.

original_dataset_dir = './multi_task_learning/data/ESPGame100k'
base_dataset_dir = './multi_task_learning/data/ESPGame100k_small'
original_label_path = original_dataset_dir + '/labels'
original_label_files = [f for f in listdir(original_label_path) if isfile(join(original_label_path, f))]
original_image_path = original_dataset_dir + '/thumbnails'
original_image_files = [f for f in listdir(original_image_path) if isfile(join(original_image_path, f))]
original_image_files = np.array(original_image_files)
original_label_files = np.array(original_label_files)
dataset_size = original_label_files.shape[0]
perm = np.arange(dataset_size)
np.random.shuffle(perm)
original_image_files = original_image_files[perm]
original_label_files = original_label_files[perm]

Untuk melatih model multi-input baru di laptop dalam jangka waktu yang wajar (beberapa jam), saya secara acak memilih 2.000 gambar dan 2.000 file tag kata yang sesuai untuk pelatihan model untuk artikel ini:

if not os.path.isdir(base_dataset_dir):
    os.mkdir(base_dataset_dir)
    
small_label_path = os.path.join(base_dataset_dir, 'labels')
small_image_path = os.path.join(base_dataset_dir, 'thumbnails')
if not os.path.isdir(small_label_path):
    os.mkdir(small_label_path)
if not os.path.isdir(small_image_path):
    os.mkdir(small_image_path)
for fname in original_label_files[:2000]:
    src = os.path.join(original_label_path, fname)
    dst = os.path.join(small_label_path, fname)
    shutil.copyfile(src, dst)
for fname in original_label_files[:2000]:
    img_fname = fname[:-5]
    src = os.path.join(original_image_path, img_fname)
    dst = os.path.join(small_image_path, img_fname)
    shutil.copyfile(src, dst)

Kode di bawah ini untuk memuat 2.000 nama file tag gambar dan 2.000 tag kata yang sesuai ke dalam Pandas DataFrame:

label_map = {'label_file' : [], 'word_tags' : []}
for fname in listdir(small_label_path): 
    f = join(small_label_path, fname)
    if isfile(f):
        f = open(f)
        label_map['label_file'].append(fname)
        line = f.read().splitlines()
        label_map['word_tags'].append(line)
label_df = pd.DataFrame(label_map)
label_df.head()

Mirip dengan [4], prosedur prapemrosesan data tekstual disertakan dalam notebook Jupyter [5] untuk melakukan prapemrosesan data minimum seperti menghapus kata-kata berhenti dan angka numerik jika hal itu membuat perbedaan yang signifikan:

Seperti yang dijelaskan dalam [4], dampak prapemrosesan data tekstual tidak signifikan sehingga tag kata mentah tanpa prapemrosesan digunakan untuk pelatihan model dalam artikel ini.

2. Arsitektur Pembelajaran Transfer Model Multi-Input

Seperti yang ditunjukkan dalam diagram di bawah, model pembelajaran transfer multi-input baru menggunakan model ConvNet terlatih VGG16 untuk menerima dan menangani gambar dan model NLP baru (kombinasi model penyematan kata terlatih GloVe dan Keras LSTM ) untuk menerima dan menangani tag kata. Kedua model masukan ini digabungkan terlebih dahulu dan kemudian digabungkan dengan model klasifikasi keluaran yang terhubung sepenuhnya yang menggunakan keluaran model pengenalan gambar dan keluaran model NLP untuk menentukan apakah pasangan masukan dari suatu gambar dan sekumpulan tag kata cocok atau tidak. pertandingan (0-Tidak, 1-Ya).

Gambar 2: Arsitektur model pembelajaran mendalam baru untuk pembelajaran transfer model multi-input.

3. Transfer Pembelajaran untuk Pengenalan Gambar

Seperti yang ditunjukkan pada Gambar 2, model pembelajaran transfer multi-input baru menggunakan model ConvNet terlatih VGG16 untuk pengenalan gambar. Model VGG16 telah disertakan di perpustakaan Keras. Kode berikut dari [1] digunakan untuk menggabungkan basis konvolusional VGG16 dengan pengklasifikasi baru yang terhubung sepenuhnya untuk membentuk model masukan pengenalan gambar baru:

from keras.applications import VGG16

image_input = Input(shape=(150, 150, 3), name='image')
vgg16 = VGG16(weights='imagenet',
                  include_top=False,
                  input_shape=(150, 150, 3))(image_input)
x = layers.Flatten()(vgg16) 
x = layers.Dense(256, activation='relu')(x)

4. Transfer Pembelajaran untuk Klasifikasi Teks

Seperti yang ditunjukkan pada Gambar 2, model pembelajaran transfer multi-input baru menggunakan model penyematan kata terlatih GloVe [3] untuk mengubah tag kata menjadi vektor kompak. Setelah kumpulan data GloVe [3] diunduh ke mesin lokal, kode berikut dari [1] dapat digunakan untuk memuat model penyematan kata ke dalam memori:

glove_dir = './multi_task_learning/data/'
embeddings_index = {}
f = open(os.path.join(glove_dir, 'glove.6B.100d.txt'))
for line in f:
    values = line.split()
    word = values[0]
    coefs = np.asarray(values[1:], dtype='float32')
    embeddings_index[word] = coefs
f.close()

Seperti terlihat pada Gambar 2, penyematan kata GloVe digabungkan dengan Keras LSTM untuk membentuk model input NLP baru untuk memprediksi/mengenali tag kata:

tag_input = Input(shape=(None,), dtype='int32', name='tag')
embedded_tag = layers.Embedding(max_words, embedding_dim)(tag_input)
encoded_tag = layers.LSTM(512)(embedded_tag)

5. Menggabungkan Model Multi-Input dengan Pengklasifikasi Terhubung Sepenuhnya

Setelah model masukan pengenalan gambar baru dan model masukan NLP baru dibuat, kode berikut dapat menggabungkannya dengan pengklasifikasi keluaran baru ke dalam satu model pembelajaran transfer multi-input:

concatenated = layers.concatenate([x, encoded_tag], axis=-1)
output = layers.Dense(1, activation='sigmoid')(concatenated)model = Model([image_input, tag_input], output)
model.summary()

Seperti dijelaskan dalam [1], basis konvolusional VGG16 yang telah dilatih sebelumnya dan lapisan penyematan kata GloVe harus dibekukan sehingga bobot model yang telah dilatih sebelumnya tidak akan diubah selama pelatihan model multi-input baru:

# model.layers[1].trainable = False # freeze VGG16
model.layers[4].set_weights([embedding_matrix])
model.layers[4].trainable = False # freeze GloVe word embedding

Namun, mengenai basis konvolusional VGG16, menarik untuk dicatat bahwa saya mencoba kedua cara tersebut (dibekukan atau tidak dibekukan), tetapi tidak melihat perbedaan yang signifikan dalam hal waktu pelatihan model atau hasil prediksi model.

6. Pelatihan Model Multi-Input

Kumpulan data pelatihan Kaggle asli hanya menyertakan pasangan gambar yang benar dan tag kata yang sesuai. Masing-masing pasangan yang benar diberi label 1 (cocok) di artikel ini (lihat juga kode di bawah). Untuk membuat kumpulan data yang seimbang, kode berikut membuat 2.000 pasangan gambar dan tag kata yang salah selain 2.000 pasangan gambar dan tag kata yang benar. Untuk mempermudah, hal ini dicapai dengan memasangkan masing-masing (katakanlah Gambar i) dari 2.000 gambar yang dipilih dengan tag kata dari file gambar berikutnya (yaitu, tag kata dari Gambar i+1).

import cv2
dim = (150, 150)
X_image_train = []
X_tag_train = tag_data
y_train = []
    
for fname in listdir(small_image_path):
    fpath = os.path.join(small_image_path, fname)
    im = cv2.imread(fpath)
    im_resized = cv2.resize(im, dim, interpolation = cv2.INTER_AREA)
    X_image_train.append(im_resized)
    y_train.append(1)
    
# add incorrect image and tag pairs
num_negative_samples = len(y_train)
for i in range(num_negative_samples):
    image = X_image_train[i]
    X_image_train.append(image)
    j = (i + 1) % num_negative_samples # get a different tag
    tag = X_tag_train[j]
    X_tag_train = np.append(X_tag_train, tag) 
    y_train.append(0)

Total ada 4.000 pasang gambar dan tag kata, 2.000 pasangan benar dan 2.000 pasangan salah.

Setiap tag kata gambar perlu dikodekan sebagai bilangan bulat, dan setiap daftar/urutan tag kata perlu diubah menjadi urutan nilai bilangan bulat sebelum tag kata dapat digunakan oleh model penyematan kata. Hal ini dicapai sebagai berikut dengan menggunakan dan memodifikasi kode di [1]:

from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
maxlen = 100
training_samples = num_of_samples
tag_vocabulary_size = 10000
max_words = tag_vocabulary_size
num_of_samples = label_df.shape[0]
tokenizer = Tokenizer(num_words=max_words)
texts = []
for tag_list in label_df_clean['word_tags']:
    texts.append(' '.join(tag_list))
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
word_index = tokenizer.word_index
print('Found {} unique tokens'.format(len(word_index)))
tag_data = pad_sequences(sequences, maxlen=maxlen)

Kumpulan data pelatihan gambar dan tag kata yang dihasilkan diubah menjadi array Numpy dan diacak untuk pelatihan model:

X_image_train = np.array(X_image_train)
X_tag_train   = np.array(X_tag_train)
y_train       = np.array(y_train)
perm = np.arange(y_train.shape[0])
np.random.shuffle(perm)
X_image_train = X_image_train[perm]
X_tag_train   = X_tag_train[perm]
y_train       = y_train[perm]

Model multi-input baru dikompilasi dan dilatih sebagai berikut hanya dengan 30 epoch dan 4.000 pasangan gambar dan tag kata yang seimbang:

model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])
model.fit([X_image_train, X_tag_train], y_train, epochs=30, batch_size=64)

7. Prediksi Model

Seperti yang ditunjukkan di bawah, kumpulan data pengujian pribadi di [2] mencakup 500 gambar dan setiap gambar dikaitkan dengan dua kumpulan tag kata:

Dengan adanya gambar dalam kumpulan data pengujian, model pembelajaran transfer multi-input yang baru harus mampu memprediksi mana dari dua kumpulan tag kata yang cocok dengan gambar tersebut.

Kode berikut untuk memuat gambar pengujian ke dalam memori:

dim = (150, 150)
X_image_test = []
for fname in listdir(test_image_dir):
    fpath = os.path.join(test_image_dir, fname)
    im = cv2.imread(fpath)
    im_resized = cv2.resize(im, dim, interpolation = cv2.INTER_AREA)
    X_image_test.append(im_resized)

Tag kata pengujian diubah menjadi urutan nilai integer yang dikodekan sebagai berikut:

tokenizer_test = Tokenizer(num_words=max_words)
texts_1 = []
texts_2 = []
texts_all = []
for tag_list in test_image_label_df['word_tags_1']:
    texts_1.append(' '.join(tag_list))
for tag_list in test_image_label_df['word_tags_2']:
    texts_2.append(' '.join(tag_list))
texts_all.extend(texts_1)
texts_all.extend(texts_2)
tokenizer_test.fit_on_texts(texts_all)
sequences_1 = tokenizer_test.texts_to_sequences(texts_1)
sequences_2 = tokenizer_test.texts_to_sequences(texts_2)
word_index_test = tokenizer_test.word_index
print('Found {} unique tokens in test'.format(len(word_index_test)))
tag_data_test_1 = pad_sequences(sequences_1, maxlen=maxlen)
tag_data_test_2 = pad_sequences(sequences_2, maxlen=maxlen)

Array gambar dan tag kata Python yang dihasilkan kemudian diubah menjadi array Numpy dan dimasukkan ke dalam model terlatih untuk prediksi:

X_image_test = np.array(X_image_test)
X_tag_test_1 = np.array(tag_data_test_1)
X_tag_test_2 = np.array(tag_data_test_2)
y_predict_1 = loaded_model.predict([X_image_test, X_tag_test_1])
y_predict_2 = loaded_model.predict([X_image_test, X_tag_test_2])

Tabel berikut menunjukkan 20 hasil prediksi pertama:

Gambar berikut adalah Gambar 201.png pada dataset pengujian:

Dua kumpulan tag kata yang terkait adalah sebagai berikut:

word-tag-set-0: ['bloom', 'glow', 'overexposed', 'bright', 'white', 'face', 'woman', 'blonde']
word-tag-set-1: ['iron', 'nuggets', 'samples', 'metal', 'ore', 'shadow', 'white', 'grey', 'gray', 'rust', 'shiny']

Model tersebut memperkirakan:

word-tag-set-0: probability of 0.797
word-tag-set-1: probability of 0.999

Jawaban dengan probabilitas lebih tinggi yaitu 0,999 adalah:

['besi', 'nugget', 'sampel', 'logam', 'bijih', 'bayangan', 'putih', 'abu-abu', 'abu-abu', 'karat', 'mengkilap' ]

Sebagai contoh positif lainnya, berikut ini adalah Gambar 76.png dalam kumpulan data pengujian:

Berikut ini adalah dua set tag kata yang terkait:

word-tag-set-0: ['person', 'man', 'shirt', 'pinstripe', 'smile', 'balding', 'grey', 'gray']
word-tag-set-1: ['country', 'music', 'man', 'instrument', 'guitar', 'musician', 'person', 'playing', 'watch', 'striped', 'shirt', 'red', 'glasses']

Model tersebut memperkirakan:

word-tag-set-0: probability of 0.997
word-tag-set-1: probability of 0.530

Jawaban dengan probabilitas lebih tinggi yaitu 0,997 adalah:

['orang', 'pria', 'kemeja', 'garis-garis', 'senyum', 'botak', 'abu-abu', 'abu-abu']

Sebagai contoh positif palsu, berikut adalah Gambar 189.png pada kumpulan data pengujian:

Berikut ini adalah dua set tag kata yang terkait:

word-tag-set-0: ['necklace', 'woman', 'earring', 'jewelry', 'mouth', 'chin', 'closeup']
word-tag-set-1: ['circle', 'lines', 'round', 'window', 'porthole', 'man', 'face', 'beard', 'person', 'dark', 'shadow']

Model tersebut memperkirakan:

word-tag-set-0: probability of 0.016
word-tag-set-1: probability of 0.999

Jawaban positif palsu dengan probabilitas lebih tinggi yaitu 0,999 adalah:

['lingkaran', 'garis', 'bulat', 'jendela', 'jendela', 'manusia', 'wajah', 'janggut', 'orang', 'gelap', 'bayangan']

Hasil pengujian di atas menunjukkan bahwa meskipun model pembelajaran transfer multi-input baru dilatih dengan hanya 4.000 pasang tag gambar dan kata serta 30 epoch, model tersebut mampu memperoleh hasil yang cukup masuk akal dalam hal akurasi.

Namun model tersebut juga menghasilkan beberapa kesalahan positif karena model overfit.

Ringkasan

Artikel ini menyajikan model pembelajaran transfer mendalam multi-input baru yang menggabungkan dua model input terlatih (VGG16 dan GloVe & LSTM) dengan lapisan klasifikasi baru yang terhubung sepenuhnya untuk mengenali gambar dan tag kata secara bersamaan.

Poin kunci dari metode pembelajaran mendalam multi-input yang baru adalah menerjemahkan masalah pengenalan gambar dan tag kata ke dalam masalah klasifikasi, yaitu menentukan apakah gambar tertentu cocok dengan kumpulan tag kata tertentu (0-Tidak, 1-Ya).

Kumpulan data publik yang menantang di Kaggle, “Tantangan dalam Pembelajaran Representasi: Pembelajaran Multi-modal” [2], digunakan untuk melatih dan mengevaluasi model baru.

Hasil prediksi model menunjukkan bahwa model baru memiliki kinerja yang cukup baik dengan pelatihan model terbatas (hanya 30 epoch dan 4.000 pasang gambar dan tag kata) untuk tujuan demonstrasi. Namun, tidak mengherankan, model tersebut juga menghasilkan cukup banyak kesalahan positif karena model yang berlebihan. Masalah ini dapat diatasi dengan melatih model dengan lebih banyak epoch dan/atau lebih banyak pasangan gambar dan tag kata.

Tampaknya 2.000 gambar pelatihan yang dipilih secara acak tidak cukup mewakili total 100.000 gambar pelatihan yang tersedia. Performa model harus ditingkatkan secara signifikan dengan meningkatkan jumlah gambar pelatihan dari 2.000 ke ukuran yang lebih besar seperti 10.000.

Notebook Jupyter dengan semua kode sumber tersedia di Github [5].

Referensi

[1] F. Chollet, Pembelajaran Mendalam dengan Python, Manning Publications Co., 2018

[2] Tantangan dalam Pembelajaran Representasi: Pembelajaran Multimodal

[3] J. Pennington, R. Socher, CD. Manning, GloVe: Vektor Global untuk Representasi Kata

[4] Y. Zhang, Pembelajaran Mendalam untuk Pemrosesan Bahasa Alami Menggunakan word2vec-keras

[5] Y. Zhang, buku catatan Jupyter di Github

PERNYATAAN PENGUNGKAPAN: © 2019 Capital One. Pendapat adalah milik masing-masing penulis. Kecuali disebutkan lain dalam postingan ini, Capital One tidak berafiliasi dengan, atau didukung oleh, perusahaan mana pun yang disebutkan. Semua merek dagang dan kekayaan intelektual lainnya yang digunakan atau ditampilkan adalah milik dari pemiliknya masing-masing.