Tôi hiện đang nghiên cứu bài báo này , trong đó CNN được áp dụng để nhận dạng âm vị bằng cách sử dụng biểu diễn trực quan của các ngân hàng bộ lọc log mel và sơ đồ chia sẻ trọng lượng hạn chế.
Hình dung của các ngân hàng bộ lọc log mel là một cách đại diện và bình thường hóa dữ liệu. Họ đề nghị hình dung như một quang phổ với màu RGB, thứ gần nhất tôi có thể nghĩ ra là vẽ nó bằng cách sử dụng matplotlibs
colormap cm.jet
. Họ (là tờ giấy) cũng đề xuất mỗi khung nên được xếp chồng lên nhau bằng năng lượng bộ lọc [delta delta_delta] của nó. Cái này trông như thế này:
Đầu vào của bao gồm một miếng vá hình ảnh gồm 15 khung hình được đặt hình dạng đầu vào [delta delta_detlta] sẽ là (40,45,3)
Chia sẻ trọng lượng giới hạn bao gồm giới hạn chia sẻ trọng lượng cho một khu vực ngân hàng bộ lọc cụ thể, vì lời nói được diễn giải khác nhau ở khu vực tần số khác nhau, do đó sẽ chia sẻ trọng lượng đầy đủ như áp dụng tích chập thông thường, sẽ không hoạt động.
Việc thực hiện chia sẻ trọng lượng hạn chế của họ bao gồm kiểm soát các trọng số trong ma trận trọng số liên quan đến từng lớp chập. Vì vậy, họ áp dụng một tích chập trên đầu vào hoàn chỉnh. Bài viết chỉ áp dụng một lớp chập vì sử dụng nhiều lớp sẽ phá hủy địa phương của các bản đồ đặc trưng được trích xuất từ lớp chập. Lý do tại sao họ sử dụng năng lượng ngân hàng bộ lọc thay vì hệ số MFCC bình thường là vì DCT phá hủy địa phương của các bộ lọc ngân hàng năng lượng.
Thay vì kiểm soát ma trận trọng số liên quan đến lớp chập, tôi chọn triển khai CNN với nhiều đầu vào. do đó, mỗi đầu vào bao gồm một (phạm vi ngân hàng bộ lọc nhỏ, Total_frames_with_deltas, 3). Vì vậy, ví dụ, trạng thái giấy rằng kích thước bộ lọc là 8 nên tốt, vì vậy tôi đã quyết định phạm vi ngân hàng bộ lọc là 8. Vì vậy, mỗi miếng vá hình ảnh nhỏ có kích thước (8,45,3). Mỗi miếng vá hình ảnh nhỏ được trích xuất với một cửa sổ trượt với sải chân là 1 - vì vậy có rất nhiều sự chồng chéo giữa mỗi đầu vào - và mỗi đầu vào có một lớp chập riêng.
(input_3, input_3, input3, đáng lẽ phải là input_1, input_2, input_3 ...)
Làm theo cách này cho phép sử dụng nhiều lớp chập, vì địa phương không còn là vấn đề nữa, vì nó được áp dụng trong khu vực ngân hàng bộ lọc, đây là lý thuyết của tôi.
Bài viết không nêu rõ nhưng tôi đoán lý do tại sao họ thực hiện nhận dạng âm vị trên nhiều khung là để có một số bối cảnh bên trái và bối cảnh bên phải, vì vậy chỉ có khung giữa được dự đoán / đào tạo. Vì vậy, trong trường hợp của tôi là 7 khung hình đầu tiên được đặt cửa sổ ngữ cảnh bên trái - khung giữa đang được đào tạo và 7 khung hình cuối cùng được đặt là cửa sổ ngữ cảnh bên phải. Vì vậy, cho nhiều khung hình, sẽ chỉ có một âm vị được công nhận là giữa.
Mạng lưới thần kinh của tôi hiện tại trông như thế này:
def model3():
#stride = 1
#dim = 40
#window_height = 8
#splits = ((40-8)+1)/1 = 33
next(test_generator())
next(train_generator(batch_size))
kernel_number = 200#int(math.ceil(splits))
list_of_input = [Input(shape = (window_height,total_frames_with_deltas,3)) for i in range(splits)]
list_of_conv_output = []
list_of_conv_output_2 = []
list_of_conv_output_3 = []
list_of_conv_output_4 = []
list_of_conv_output_5 = []
list_of_max_out = []
for i in range(splits):
#list_of_conv_output.append(Conv2D(filters = kernel_number , kernel_size = (15,6))(list_of_input[i]))
#list_of_conv_output.append(Conv2D(filters = kernel_number , kernel_size = (window_height-1,3))(list_of_input[i]))
list_of_conv_output.append(Conv2D(filters = kernel_number , kernel_size = (window_height,3), activation = 'relu')(list_of_input[i]))
list_of_conv_output_2.append(Conv2D(filters = kernel_number , kernel_size = (1,5))(list_of_conv_output[i]))
list_of_conv_output_3.append(Conv2D(filters = kernel_number , kernel_size = (1,7))(list_of_conv_output_2[i]))
list_of_conv_output_4.append(Conv2D(filters = kernel_number , kernel_size = (1,11))(list_of_conv_output_3[i]))
list_of_conv_output_5.append(Conv2D(filters = kernel_number , kernel_size = (1,13))(list_of_conv_output_4[i]))
#list_of_conv_output_3.append(Conv2D(filters = kernel_number , kernel_size = (3,3),padding='same')(list_of_conv_output_2[i]))
list_of_max_out.append((MaxPooling2D(pool_size=((1,11)))(list_of_conv_output_5[i])))
merge = keras.layers.concatenate(list_of_max_out)
print merge.shape
reshape = Reshape((total_frames/total_frames,-1))(merge)
dense1 = Dense(units = 1000, activation = 'relu', name = "dense_1")(reshape)
dense2 = Dense(units = 1000, activation = 'relu', name = "dense_2")(dense1)
dense3 = Dense(units = 145 , activation = 'softmax', name = "dense_3")(dense2)
#dense4 = Dense(units = 1, activation = 'linear', name = "dense_4")(dense3)
model = Model(inputs = list_of_input , outputs = dense3)
model.compile(loss="categorical_crossentropy", optimizer="SGD" , metrics = [metrics.categorical_accuracy])
reduce_lr=ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=1, mode='auto', epsilon=0.001, cooldown=0)
stop = EarlyStopping(monitor='val_loss', min_delta=0, patience=5, verbose=1, mode='auto')
print model.summary()
raw_input("okay?")
hist_current = model.fit_generator(train_generator(batch_size),
steps_per_epoch=10,
epochs = 10000,
verbose = 1,
validation_data = test_generator(),
validation_steps=1)
#pickle_safe = True,
#workers = 4)
Vì vậy, bây giờ đến vấn đề ..
Tôi đã đào tạo mạng và chỉ có thể có được xác thực_accuracy cao nhất là 0,17 và độ chính xác sau khi rất nhiều kỷ nguyên kết thúc là 1.0. (Lô đất hiện đang được thực hiện)
khung cố định:
(cốt truyện vẫn đang được thực hiện)
Tôi không chắc tại sao tôi không nhận được kết quả tốt hơn .. Tại sao tỷ lệ lỗi cao này? Tôi đang sử dụng bộ dữ liệu TIMIT mà những người khác cũng sử dụng .. vậy tại sao tôi lại nhận được kết quả tồi tệ hơn?
Và xin lỗi vì bài viết dài - hy vọng nhiều thông tin hơn về quyết định thiết kế của tôi có thể hữu ích - và giúp hiểu cách tôi hiểu bài viết so với cách tôi đã áp dụng sẽ giúp xác định chính xác lỗi của tôi.