#python #tensorflow #audio #deep-learning #transfer-learning
Вопрос:
Мне нужно сделать классификацию звука CNN по данным о насекомых. у меня есть очень небольшой набор данных из 158 записей и 9 классов. Мне нужно выполнить обучение передаче с использованием предварительно обученной модели AudioSet. Я следовал инструкциям на веб-сайте tensorflow: https://www.tensorflow.org/tutorials/audio/transfer_learning_audio но я не могу заставить это работать, так как я получаю постоянную низкую подготовку (40%) и точность проверки (10%) во все эпохи и 80% в тесте. Я не понимаю, почему это так и что я делаю не так. я думаю, что проблема заключается в разделении проверочного теста на обучение. Ниже приведен код:
yamnet_model_handle = 'https://tfhub.dev/google/yamnet/1'
yamnet_model = hub.load(yamnet_model_handle)
def load_wav_16k_mono(filename):
""" Load a WAV file, convert it to a float tensor, resample to 16 kHz single-channel audio. """
file_contents = tf.io.read_file(filename)
wav, sample_rate = tf.audio.decode_wav(
file_contents,
desired_channels=1)
wav = tf.squeeze(wav, axis=-1)
sample_rate = tf.cast(sample_rate, dtype=tf.int64)
wav = tfio.audio.resample(wav, rate_in=sample_rate, rate_out=16000)
return wav
class_map_path = yamnet_model.class_map_path().numpy().decode('utf-8')
class_names =list(pd.read_csv(class_map_path)['display_name'])
for name in class_names[:20]:
print(name)
print('...')
enter code here
metadataf = "C:\Users\Thesis_PC\orthoptera\metadata.csv"
base_data_path = "C:\Users\Thesis_PC\orthoptera\resized16\"
metadata = pd.read_csv(metadataf)
metadata.head()
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
metadata['species'] = encoder.fit_transform(metadata['species'])
metadata.head()
my_classes = ["Chorthippus biguttulus",
"Chorthippus brunneus",
"Gryllus campestris",
"Nemobius sylvestris",
"Oecanthus pellucens",
"Pholidoptera griseoaptera",
"Pseudochorthippus parallelus" ,
"Roeseliana roeselii",
"Tettigonia viridissima"]
full_path = metadata['id'].apply(lambda row: os.path.join(base_data_path, row))
metadata = metadata.assign(id=full_path)
filenames = metadata['id']
targets = metadata['species']
main_ds = tf.data.Dataset.from_tensor_slices((filenames, targets))
main_ds.element_spec
metadata.head(100)
def load_wav_for_map(filename, label):
return load_wav_16k_mono(filename), label
main_ds = main_ds.map(load_wav_for_map)
main_ds.element_spec
# applies the embedding extraction model to a wav data
def extract_embedding(wav_data, label):
''' run YAMNet to extract embedding from the wav data '''
scores, embeddings, spectrogram = yamnet_model(wav_data)
num_embeddings = tf.shape(embeddings)[0]
return (embeddings,
tf.repeat(label, num_embeddings))
# extract embedding
main_ds = main_ds.map(extract_embedding).unbatch()
main_ds.element_spec
main_ds = main_ds.cache().shuffle(1000)
train_size = 130
val_size = 18
test_size = 10
train_ds = main_ds.take(train_size)
test_ds = main_ds.skip(train_size)
val_ds = test_ds.skip(test_size)
test_ds = test_ds.take(test_size)
train_ds = train_ds.cache().shuffle(15).batch(5).prefetch(tf.data.AUTOTUNE)
val_ds = val_ds.cache().batch(5).prefetch(tf.data.AUTOTUNE)
test_ds = test_ds.cache().batch(5).prefetch(tf.data.AUTOTUNE)
my_model = tf.keras.Sequential([
tf.keras.layers.Input(shape=(1024), dtype=tf.float32,
name='input_embedding'),
tf.keras.layers.Dense(256, activation='softmax'),
tf.keras.layers.Dense(9)
], name='my_model')
my_model.summary()
my_model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=["accuracy"])
history = my_model.fit(train_ds,
epochs=5,
validation_data=val_ds)
Ответ №1:
Вы используете категориальную перекрестную энтропию в качестве функции потерь, поэтому вам нужно поместить активацию softmax в последний плотный слой вашей модели :
my_model = tf.keras.Sequential([
tf.keras.layers.Input(shape=(1024), dtype=tf.float32,
name='input_embedding'),
tf.keras.layers.Dense(256, activation='relu'),
tf.keras.layers.Dense(9, activation='softmax')
], name='my_model')
Другой вариант-не включать активацию на последнем уровне и регистрировать логины в функции потерь, как в коде tensorflow, на который вы ссылаетесь:
my_model.compile(loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
optimizer="adam",
metrics=['accuracy'])
Комментарии:
1. Спасибо вам за ваш ответ. теперь это выглядит лучше, но есть еще одна проблема. точность поезда составляет около 90%, в то время как точность проверки постоянна около 23%, в то время как набор тестов составляет 80%. Как так вышло? является ли модель замораживанием последних слоев или просто добавлением слоев сверху?