Làm thế nào để thực hiện dự đoán trình tự một-nhiều-nhiều-nhiều-nhiều-một-nhiều-nhiều-một-nhiều-nhiều trong các máy ảnh?


13

Tôi đấu tranh để giải thích sự khác biệt mã hóa Keras cho việc ghi nhãn một-nhiều (ví dụ: phân loại các hình ảnh đơn lẻ) và nhiều thứ tự (ví dụ như phân loại các chuỗi hình ảnh). Tôi thường thấy hai loại mã khác nhau:

Loại 1 là nơi không áp dụng TimeDistribution như thế này:

model=Sequential()

model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1], border_mode="valid", input_shape=[1, 56,14]))
model.add(Activation("relu"))
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1]))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=pool_size))

model.add(Reshape((56*14,)))
model.add(Dropout(0.25))
model.add(LSTM(5))
model.add(Dense(50))
model.add(Dense(nb_classes))
model.add(Activation("softmax"))

Loại 2 là nơi TimeDistribution được áp dụng như thế này:

model = Sequential()

model.add(InputLayer(input_shape=(5, 224, 224, 3)))
model.add(TimeDistributed(Convolution2D(64, (3, 3))))
model.add(TimeDistributed(MaxPooling2D((2,2), strides=(2,2))))
model.add(LSTM(10))
model.add(Dense(3))

Câu hỏi của tôi là:

  • Giả định của tôi có đúng không khi Loại 1 là loại một-nhiều và Loại 2 là loại nhiều-nhiều? Hoặc TimeDistributedkhông có liên quan trong khía cạnh này?

  • Trong cả hai trường hợp một hoặc nhiều hoặc nhiều là lớp dày đặc cuối cùng được coi là 1 nút "dài" (chỉ phát ra một giá trị lần lượt) và
    lớp lặp lại trước đó có trách nhiệm xác định có bao nhiêu
    1 lần Giá trị để phát ra? Hoặc lớp dày đặc cuối cùng được cho là bao gồm N nút ở đâu N=max sequence length? Nếu vậy, điểm
    sử dụng RNN ở đây là gì khi chúng ta có thể tạo ra một đầu vào tương tự với nhiều
    đầu ra với N ước tính "vanilla" song song?

  • Làm cách nào để xác định số lượng dấu thời gian trong RNN? Là nó bằng cách nào đó
    tương quan với độ dài chuỗi đầu ra hoặc nó chỉ là một
    siêu tham số để điều chỉnh?

  • Trường hợp trong ví dụ Loại 1 của tôi ở trên điểm áp dụng
    LSTM là gì khi mô hình chỉ phát ra một dự đoán lớp (có thể
    nb_classes)? Điều gì nếu một người bỏ qua lớp LSTM?


Bạn có thể cung cấp bản tóm tắt của cả hai mô hình?
Fadi Bakoura

Câu trả lời:


2

Điểm của việc sử dụng bất kỳ lớp lặp lại nào là có đầu ra là kết quả của không chỉ một mục duy nhất độc lập với các mục khác, mà là một chuỗi các mục, sao cho đầu ra của hoạt động của lớp trên một mục trong chuỗi là kết quả của cả mặt hàng đó và bất kỳ mặt hàng nào trước nó trong chuỗi. Số lượng dấu thời gian xác định khoảng thời gian như vậy là bao lâu. Đó là, có bao nhiêu mục nên được xử lý theo trình tự và ảnh hưởng đến kết quả đầu ra của nhau.

Một lớp LSTM hoạt động theo cách nó chấp nhận đầu vào trên biểu mẫu number_of_timesteps, kích thước_of_each_item. Nếu tham số return_ resultences được đặt thành false, theo mặc định, lớp "hợp chất" các đầu vào của tất cả các dấu thời gian thành một đầu ra duy nhất. Nếu bạn xem xét một chuỗi gồm 10 mục, một lớp LSTM với return_ resultences được đặt thành Sai sẽ từ một chuỗi như vậy tạo ra một mục đầu ra duy nhất và các thuộc tính của mục này sẽ là kết quả của tất cả các mục (dấu thời gian) trong sự nối tiếp. Đây là những gì bạn muốn trong trường hợp thiết kế nhiều-một.

Một lớp LSTM với return_ resultences được đặt thành True will cho mỗi mục (dấu thời gian) trong chuỗi đầu vào tạo ra một đầu ra. Điều này được thực hiện theo cách mà tại bất kỳ dấu thời gian nào, đầu ra sẽ không chỉ phụ thuộc vào mục hiện đang được vận hành mà còn cả các mục trước đó trong chuỗi. Đây là những gì bạn muốn trong trường hợp thiết kế nhiều-nhiều.

Vì một lớp LSTM lấy một chuỗi các mục làm đầu vào, bất kỳ lớp nào trước một lớp LSTM trong mô hình của bạn sẽ cần phải tạo ra một chuỗi như một đầu ra. Trong trường hợp mô hình Loại 1 của bạn, một vài lớp đầu tiên không hoạt động theo trình tự, mà thay vào đó là một mục duy nhất tại một thời điểm. Do đó, điều này không tạo ra một chuỗi các mục để vận hành cho LSTM.

Sử dụng TimeDistribution cho phép một lớp hoạt động trên mọi mục theo trình tự mà không có các mục ảnh hưởng lẫn nhau. Do đó, các lớp TimeDistribution hoạt động theo chuỗi các mục, nhưng không có đệ quy.

Trong trường hợp của mô hình loại 2 của bạn, các lớp đầu tiên sẽ tạo ra một chuỗi 5 dấu thời gian dài và các thao tác được thực hiện trên từng mục trong chuỗi sẽ độc lập với nhau, vì các lớp được bọc trong TimeDistribution không lặp lại. Vì lớp LSTM sử dụng các cài đặt mặc định, return_ resultences = false, lớp LSTM sẽ tạo ra một đầu ra duy nhất cho mỗi chuỗi 5 mục như vậy.

Số nút đầu ra cuối cùng trong mô hình của bạn phụ thuộc hoàn toàn vào trường hợp sử dụng. Một nút duy nhất phù hợp cho một cái gì đó như phân loại nhị phân hoặc để tạo ra một số loại điểm.


1

Tôi nghĩ rằng bạn có thể có thể sử dụng công việc trước đây của tôi. Trong mã này, tôi tạo ra các sóng hình sin (có bước sóng và pha ngẫu nhiên) và huấn luyện một LSTM đến một chuỗi các điểm từ các sóng hình sin này và tạo ra một chuỗi 150 điểm hoàn thành mỗi sóng hình sin.

Đây là mô hình:

    features_num=5 
    latent_dim=40

    ##
    encoder_inputs = Input(shape=(None, features_num))
    encoded = LSTM(latent_dim, return_state=False ,return_sequences=True)(encoder_inputs)
    encoded = LSTM(latent_dim, return_state=False ,return_sequences=True)(encoded)
    encoded = LSTM(latent_dim, return_state=False ,return_sequences=True)(encoded)
    encoded = LSTM(latent_dim, return_state=True)(encoded)

    encoder = Model (input=encoder_inputs, output=encoded)
    ##

    encoder_outputs, state_h, state_c = encoder(encoder_inputs)
    encoder_states = [state_h, state_c]

    decoder_inputs=Input(shape=(1, features_num))
    decoder_lstm_1 = LSTM(latent_dim, return_sequences=True, return_state=True)
    decoder_lstm_2 = LSTM(latent_dim, return_sequences=True, return_state=True)
    decoder_lstm_3 = LSTM(latent_dim, return_sequences=True, return_state=True)
    decoder_lstm_4 = LSTM(latent_dim, return_sequences=True, return_state=True)

    decoder_dense = Dense(features_num)

    all_outputs = []
    inputs = decoder_inputs


    states_1=encoder_states
   # Place holder values:
    states_2=states_1; states_3=states_1; states_4=states_1

    for _ in range(1):
        # Run the decoder on the first timestep
        outputs_1, state_h_1, state_c_1 = decoder_lstm_1(inputs, initial_state=states_1)
        outputs_2, state_h_2, state_c_2 = decoder_lstm_2(outputs_1)
        outputs_3, state_h_3, state_c_3 = decoder_lstm_3(outputs_2)
        outputs_4, state_h_4, state_c_4 = decoder_lstm_4(outputs_3)

        # Store the current prediction (we will concatenate all predictions later)
        outputs = decoder_dense(outputs_4)
        all_outputs.append(outputs)
        # Reinject the outputs as inputs for the next loop iteration
        # as well as update the states
        inputs = outputs
        states_1 = [state_h_1, state_c_1]
        states_2 = [state_h_2, state_c_2]
        states_3 = [state_h_3, state_c_3]
        states_4 = [state_h_4, state_c_4]


    for _ in range(149):
        # Run the decoder on each timestep
        outputs_1, state_h_1, state_c_1 = decoder_lstm_1(inputs, initial_state=states_1)
        outputs_2, state_h_2, state_c_2 = decoder_lstm_2(outputs_1, initial_state=states_2)
        outputs_3, state_h_3, state_c_3 = decoder_lstm_3(outputs_2, initial_state=states_3)
        outputs_4, state_h_4, state_c_4 = decoder_lstm_4(outputs_3, initial_state=states_4)

        # Store the current prediction (we will concatenate all predictions later)
        outputs = decoder_dense(outputs_4)
        all_outputs.append(outputs)
        # Reinject the outputs as inputs for the next loop iteration
        # as well as update the states
        inputs = outputs
        states_1 = [state_h_1, state_c_1]
        states_2 = [state_h_2, state_c_2]
        states_3 = [state_h_3, state_c_3]
        states_4 = [state_h_4, state_c_4]


    # Concatenate all predictions
    decoder_outputs = Lambda(lambda x: K.concatenate(x, axis=1))(all_outputs)   

    model = Model([encoder_inputs, decoder_inputs], decoder_outputs)

    #model = load_model('pre_model.h5')


    print(model.summary())

Và đây là toàn bộ kịch bản:

from keras.models import Model
from keras.layers import Input, LSTM, Dense, TimeDistributed,Lambda, Dropout, Activation ,RepeatVector
from keras.callbacks import ModelCheckpoint 
import numpy as np

from keras.layers import Lambda
from keras import backend as K

from keras.models import load_model

import os


features_num=5 
latent_dim=40

##
encoder_inputs = Input(shape=(None, features_num))
encoded = LSTM(latent_dim, return_state=False ,return_sequences=True)(encoder_inputs)
encoded = LSTM(latent_dim, return_state=False ,return_sequences=True)(encoded)
encoded = LSTM(latent_dim, return_state=False ,return_sequences=True)(encoded)
encoded = LSTM(latent_dim, return_state=True)(encoded)

encoder = Model (input=encoder_inputs, output=encoded)
##

encoder_outputs, state_h, state_c = encoder(encoder_inputs)
encoder_states = [state_h, state_c]

decoder_inputs=Input(shape=(1, features_num))
decoder_lstm_1 = LSTM(latent_dim, return_sequences=True, return_state=True)
decoder_lstm_2 = LSTM(latent_dim, return_sequences=True, return_state=True)
decoder_lstm_3 = LSTM(latent_dim, return_sequences=True, return_state=True)
decoder_lstm_4 = LSTM(latent_dim, return_sequences=True, return_state=True)

decoder_dense = Dense(features_num)

all_outputs = []
inputs = decoder_inputs

# Place holder values:
states_1=encoder_states
states_2=states_1; states_3=states_1; states_4=states_1

for _ in range(1):
    # Run the decoder on one timestep
    outputs_1, state_h_1, state_c_1 = decoder_lstm_1(inputs, initial_state=states_1)
    outputs_2, state_h_2, state_c_2 = decoder_lstm_2(outputs_1)
    outputs_3, state_h_3, state_c_3 = decoder_lstm_3(outputs_2)
    outputs_4, state_h_4, state_c_4 = decoder_lstm_4(outputs_3)

    # Store the current prediction (we will concatenate all predictions later)
    outputs = decoder_dense(outputs_4)
    all_outputs.append(outputs)
    # Reinject the outputs as inputs for the next loop iteration
    # as well as update the states
    inputs = outputs
    states_1 = [state_h_1, state_c_1]
    states_2 = [state_h_2, state_c_2]
    states_3 = [state_h_3, state_c_3]
    states_4 = [state_h_4, state_c_4]


for _ in range(149):
    # Run the decoder on one timestep
    outputs_1, state_h_1, state_c_1 = decoder_lstm_1(inputs, initial_state=states_1)
    outputs_2, state_h_2, state_c_2 = decoder_lstm_2(outputs_1, initial_state=states_2)
    outputs_3, state_h_3, state_c_3 = decoder_lstm_3(outputs_2, initial_state=states_3)
    outputs_4, state_h_4, state_c_4 = decoder_lstm_4(outputs_3, initial_state=states_4)

    # Store the current prediction (we will concatenate all predictions later)
    outputs = decoder_dense(outputs_4)
    all_outputs.append(outputs)
    # Reinject the outputs as inputs for the next loop iteration
    # as well as update the states
    inputs = outputs
    states_1 = [state_h_1, state_c_1]
    states_2 = [state_h_2, state_c_2]
    states_3 = [state_h_3, state_c_3]
    states_4 = [state_h_4, state_c_4]


# Concatenate all predictions
decoder_outputs = Lambda(lambda x: K.concatenate(x, axis=1))(all_outputs)   

model = Model([encoder_inputs, decoder_inputs], decoder_outputs)

#model = load_model('pre_model.h5')


print(model.summary())


model.compile(loss='mean_squared_error', optimizer='adam')


def create_wavelength(min_wavelength, max_wavelength, fluxes_in_wavelength, category )  :         
#category :: 0 - train ; 2 - validate ; 4- test. 1;3;5 - dead space
    c=(category+np.random.random())/6         
    k = fluxes_in_wavelength
#
    base= (np.trunc(k*np.random.random()*(max_wavelength-min_wavelength))       +k*min_wavelength)  /k
    answer=base+c/k
    return (answer)       

def make_line(length,category):
    shift= np.random.random()
    wavelength = create_wavelength(30,10,1,category)
    a=np.arange(length)
    answer=np.sin(a/wavelength+shift)
    return answer

def make_data(seq_num,seq_len,dim,category):
    data=np.array([]).reshape(0,seq_len,dim)
    for i in range (seq_num):
        mini_data=np.array([]).reshape(0,seq_len)
        for j in range (dim):
            line = make_line(seq_len,category)
            line=line.reshape(1,seq_len)            
            mini_data=np.append(mini_data,line,axis=0)
        mini_data=np.swapaxes(mini_data,1,0)
        mini_data=mini_data.reshape(1,seq_len,dim)      
        data=np.append(data,mini_data,axis=0)
    return (data)


def train_generator():
    while True:
        sequence_length = np.random.randint(150, 300)+150       
        data=make_data(1000,sequence_length,features_num,0) # category=0 in train


    #   decoder_target_data is the same as decoder_input_data but offset by one timestep

        encoder_input_data = data[:,:-150,:] # all but last 150 

        decoder_input_data = data[:,-151,:] # the one before the last 150.
        decoder_input_data=decoder_input_data.reshape((decoder_input_data.shape[0],1,decoder_input_data.shape[1]))


        decoder_target_data = (data[:, -150:, :]) # last 150        
        yield [encoder_input_data, decoder_input_data], decoder_target_data
def val_generator():
    while True:

        sequence_length = np.random.randint(150, 300)+150       
        data=make_data(1000,sequence_length,features_num,2) # category=2 in val

        encoder_input_data = data[:,:-150,:] # all but last 150 

        decoder_input_data = data[:,-151,:] # the one before the last 150.
        decoder_input_data=decoder_input_data.reshape((decoder_input_data.shape[0],1,decoder_input_data.shape[1]))

        decoder_target_data = (data[:, -150:, :]) # last 150        
        yield [encoder_input_data, decoder_input_data], decoder_target_data

filepath_for_w= 'flux_p2p_s2s_model.h5' 
checkpointer=ModelCheckpoint(filepath_for_w, monitor='val_loss', verbose=0, save_best_only=True, mode='auto', period=1)     
model.fit_generator(train_generator(),callbacks=[checkpointer], steps_per_epoch=30, epochs=2000, verbose=1,validation_data=val_generator(),validation_steps=30)
model.save(filepath_for_w)




def predict_wave(input_wave,input_for_decoder):  # input wave= x[n,:,:], ie points except the last 150; each wave has feature_num features. run this function for all such instances (=n)   
    #print (input_wave.shape)
    #print (input_for_decoder.shape)
    pred= model.predict([input_wave,input_for_decoder])

    return pred

def predict_many_waves_from_input(x):   
    x, x2=x # x == encoder_input_data ; x==2 decoder_input_data

    instance_num= x.shape[0]


    multi_predict_collection=np.zeros((x.shape[0],150,x.shape[2]))

    for n in range(instance_num):
        input_wave=x[n,:,:].reshape(1,x.shape[1],x.shape[2])
        input_for_decoder=x2[n,:,:].reshape(1,x2.shape[1],x2.shape[2])
        wave_prediction=predict_wave(input_wave,input_for_decoder)
        multi_predict_collection[n,:,:]=wave_prediction
    return (multi_predict_collection)

def test_maker():
    if True:        
        sequence_length = np.random.randint(150, 300)+150       
        data=make_data(470,sequence_length,features_num,4) # category=4 in test

        encoder_input_data = data[:,:-150,:] # all but last 150 

        decoder_input_data = data[:,-151,:] # the one before the last 150.
        decoder_input_data=decoder_input_data.reshape((decoder_input_data.shape[0],1,decoder_input_data.shape[1]))

        decoder_target_data = (data[:, -150:, :]) # last 150        
        return [encoder_input_data, decoder_input_data],    decoder_target_data

x,y= test_maker()   



a=predict_many_waves_from_input (x) # is that right..?
x=x[0] # keep the wave (generated data except last 150 time points) 
print (x.shape)
print (y.shape)
print (a.shape)

np.save ('a.npy',a)
np.save ('y.npy',y)
np.save ('x.npy',x)



print (np.mean(np.absolute(y[:,:,0]-a[:,:,0])))
print (np.mean(np.absolute(y[:,:,1]-a[:,:,1])))
print (np.mean(np.absolute(y[:,:,2]-a[:,:,2])))
print (np.mean(np.absolute(y[:,:,3]-a[:,:,3])))
print (np.mean(np.absolute(y[:,:,4]-a[:,:,4])))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.