কেরাস, প্রতিটি স্তরের আউটপুট কীভাবে পাবেন?


155

আমি সিএনএন এর সাথে বাইনারি শ্রেণিবদ্ধকরণের মডেলটি প্রশিক্ষণ পেয়েছি এবং এখানে আমার কোড রয়েছে

model = Sequential()
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1],
                        border_mode='valid',
                        input_shape=input_shape))
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))
# (16, 16, 32)
model.add(Convolution2D(nb_filters*2, kernel_size[0], kernel_size[1]))
model.add(Activation('relu'))
model.add(Convolution2D(nb_filters*2, kernel_size[0], kernel_size[1]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=pool_size))
# (8, 8, 64) = (2048)
model.add(Flatten())
model.add(Dense(1024))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(2))  # define a binary classification problem
model.add(Activation('softmax'))

model.compile(loss='categorical_crossentropy',
              optimizer='adadelta',
              metrics=['accuracy'])
model.fit(x_train, y_train,
          batch_size=batch_size,
          nb_epoch=nb_epoch,
          verbose=1,
          validation_data=(x_test, y_test))

এবং এখানে, আমি প্রতিটি স্তরের আউটপুট টেনসরফ্লোয়ের মতো পেতে চাই, আমি কীভাবে এটি করতে পারি?

উত্তর:


182

আপনি সহজেই যে কোনও স্তরের আউটপুটগুলি ব্যবহার করে পেতে পারেন: model.layers[index].output

সমস্ত স্তরগুলির জন্য এটি ব্যবহার করুন:

from keras import backend as K

inp = model.input                                           # input placeholder
outputs = [layer.output for layer in model.layers]          # all layer outputs
functors = [K.function([inp, K.learning_phase()], [out]) for out in outputs]    # evaluation functions

# Testing
test = np.random.random(input_shape)[np.newaxis,...]
layer_outs = [func([test, 1.]) for func in functors]
print layer_outs

নোট: ঝরে পড়া ব্যবহার অনুকরণ learning_phaseযেমন 1.মধ্যে layer_outsঅন্যথায় ব্যবহার0.

সম্পাদনা: (মন্তব্যের ভিত্তিতে)

K.function পরে ইনপুট প্রদত্ত প্রতীকী গ্রাফ থেকে আউটপুট পেতে ব্যবহৃত হবে যা পরবর্তীতে ট্যানোআর / টেনসরফ্লো টেনসর ফাংশন তৈরি করে।

K.learning_phase()ড্রপআউট / ব্যাচনমালাইজেশনের মতো অনেক কেরাস স্তর প্রশিক্ষণের সময় এবং পরীক্ষার সময় আচরণ পরিবর্তন করতে এর উপর নির্ভর করে এখন একটি ইনপুট হিসাবে এখন প্রয়োজনীয়।

সুতরাং আপনি যদি নিজের কোডের ড্রপআউট স্তরটি সরিয়ে থাকেন তবে আপনি কেবল ব্যবহার করতে পারেন:

from keras import backend as K

inp = model.input                                           # input placeholder
outputs = [layer.output for layer in model.layers]          # all layer outputs
functors = [K.function([inp], [out]) for out in outputs]    # evaluation functions

# Testing
test = np.random.random(input_shape)[np.newaxis,...]
layer_outs = [func([test]) for func in functors]
print layer_outs

সম্পাদনা 2: আরও অনুকূলিতকরণ

আমি কেবল বুঝতে পেরেছি যে পূর্ববর্তী উত্তরটি প্রতিটি ফাংশন মূল্যায়নের হিসাবে অনুকূলিত নয় যে ডেটা সিপিইউ-> জিপিইউ মেমরি স্থানান্তরিত হবে এবং এছাড়াও টেনসরের গণনাগুলি নিম্ন স্তরের ওভার-এন-ওভারের জন্য করা দরকার।

পরিবর্তে এটি আরও ভাল উপায় যেহেতু আপনার একাধিক ফাংশন প্রয়োজন নেই তবে একটি একক ফাংশন আপনাকে সমস্ত আউটপুটগুলির তালিকা প্রদান করবে:

from keras import backend as K

inp = model.input                                           # input placeholder
outputs = [layer.output for layer in model.layers]          # all layer outputs
functor = K.function([inp, K.learning_phase()], outputs )   # evaluation function

# Testing
test = np.random.random(input_shape)[np.newaxis,...]
layer_outs = functor([test, 1.])
print layer_outs

2
স্যার, আপনার উত্তরটি ভাল, K.function([inp]+ [K.learning_phase()], [out])আপনার কোডের অর্থ কী?
GoingMyWay

দুর্দান্ত উত্তর, এ np.random.random(input_shape)[np.newaxis,...]হিসাবেও লেখা যেতে পারেnp.random.random(input_shape)[np.newaxis,:]
টম

K.function কি? এটি জিপিইউতে (এমপিআই?) কীভাবে পাস হবে? পর্দার পিছনে কি আছে? এটি চুদা-র সাথে কীভাবে আলোচনা হচ্ছে? সোর্স কোডটি কোথায়?
স্টাভ বডিক

3
@ স্ট্যাভবডিক মডেল K.function এখানে ব্যবহার করে পূর্বাভাস ফাংশন তৈরি করে এবং পূর্বাভাস এটি এখানে পূর্বাভাস লুপে ব্যবহার করে । ভবিষ্যদ্বাণীটি ব্যাচের আকারের উপরে লুপ করে (যদি এটি ডিফল্ট 32 না করে সেট করে) তবে জিপিইউ মেমরির সীমাবদ্ধতাগুলি হ্রাস করতে পারে। সুতরাং আপনি কেন পর্যবেক্ষণ model.predictকরছেন তাড়াতাড়ি নিশ্চিত am
ইন্দ্রাফোরিয়ু

1
আমি এটি পাচ্ছি: অবৈধ অরগমেন্টমেন্ট এরর: S_input_39: 0 উভয়ই খাওয়ানো এবং আনছে। ... ধারণা আছে কেউ?
ম্যাথটিক

137

Https://keras.io/getting-started/faq/#how-can-i-obtain-the-output-of-an-interedia-layer থেকে

একটি সহজ উপায় হ'ল একটি নতুন মডেল তৈরি করা যা আপনার আগ্রহী স্তরগুলিকে আউটপুট দেবে:

from keras.models import Model

model = ...  # include here your original model

layer_name = 'my_layer'
intermediate_layer_model = Model(inputs=model.input,
                                 outputs=model.get_layer(layer_name).output)
intermediate_output = intermediate_layer_model.predict(data)

বিকল্পভাবে, আপনি একটি কেরাস ফাংশন তৈরি করতে পারেন যা একটি নির্দিষ্ট ইনপুট প্রদত্ত একটি নির্দিষ্ট স্তরের আউটপুট ফিরিয়ে দেবে, উদাহরণস্বরূপ:

from keras import backend as K

# with a Sequential model
get_3rd_layer_output = K.function([model.layers[0].input],
                                  [model.layers[3].output])
layer_output = get_3rd_layer_output([x])[0]

যদি আমি আপনাকে দু'বার দিতে পারতাম, যখন আপনার একগুচ্ছ ইনপুট থাকে তখন এই উপায়টি আরও বেশি সুবিধাজনক।
ড্যান ইরেজ

এটি আপনার কোড থেকে উপরের স্পষ্টরূপে তবে আমার বোধগম্যতার দ্বিগুণ পরীক্ষা করার জন্য: বিদ্যমান মডেল থেকে মডেল তৈরি করার পরে (ধরে নেওয়া এটি ইতিমধ্যে প্রশিক্ষিত), নতুন মডেলটিতে সেট_ওয়েট কল করার দরকার নেই। এটা কি ঠিক?
জেজেড

layer_output = get_3rd_layer_output([X, 0])[0]এবং layer_output = get_3rd_layer_output([X, 1])[0]ডক্সের মধ্যে তফাত কী আছে ট্রেনের মোড এবং পরীক্ষা মোডের কথা উল্লেখ করে
জেসন

দুঃখিত, আপনি কি আমাকে ব্যাখ্যা করতে পারেন এই মডেলটি ঠিক কী করে? আপনারও কি এটিকে প্রশিক্ষণ দিতে হবে? আমি এটির কোনও চিত্র কল্পনাও করতে পারি না। আপনি অন্য কোনও মডেলের ইনপুট স্তর যুক্ত করেন, তারপরে আউটপুট হিসাবে সেই অন্য মডেলের একটি এলোমেলো মধ্যবর্তী স্তর যুক্ত করুন এবং এতে ফিড ইনপুটগুলি? আসল মডেলটিকে খাওয়ানোর পরিবর্তে এবং কেন কোনও মধ্যস্থতাকারী স্তরটিতে এটি সরাসরি প্রবেশ করতে পারে? কেন এই অতিরিক্ত অদ্ভুত মডেল তৈরি? এবং এটি আউটপুট প্রভাবিত করবে না? এটি শিখতে বা প্রশিক্ষণের প্রয়োজন হবে না, বা স্তরটি মূল মডেল থেকে প্রশিক্ষিত পূর্বের নিজস্ব ওজন নিয়ে আসে?
পেড্রোড

19

এই থ্রেডের সমস্ত ভাল উত্তরের উপর ভিত্তি করে, প্রতিটি স্তরের আউটপুট আনতে আমি একটি গ্রন্থাগার লিখেছিলাম। এটি সমস্ত জটিলতা বিমূর্ত করে এবং যতটা সম্ভব ব্যবহারকারী বান্ধব হিসাবে ডিজাইন করা হয়েছে:

https://github.com/philipperemy/keract

এটি প্রায় সমস্ত প্রান্তের কেস পরিচালনা করে

আশা করি এটা সাহায্য করবে!


8

নিম্নলিখিতটি আমার কাছে খুব সহজ দেখাচ্ছে:

model.layers[idx].output

উপরে একটি সেন্সর অবজেক্ট রয়েছে, সুতরাং আপনি এটি টেনসর অবজেক্টে প্রয়োগ করা যেতে পারে এমন ক্রিয়াকলাপগুলি ব্যবহার করে এটি সংশোধন করতে পারেন।

উদাহরণস্বরূপ, আকৃতি পেতে model.layers[idx].output.get_shape()

idx এটি স্তরটির সূচক এবং আপনি এটি থেকে এটি খুঁজে পেতে পারেন model.summary()


1
এই উত্তরটিতে কি দোষ? কেন এটি শীর্ষ উত্তর হিসাবে আপভোটড হয় না?
ব্ল্যাক জ্যাক 21

1
এটি একটি টেনসর অবজেক্ট ফিরিয়ে দেয়, ডেটাফ্রেম নয়। tf অবজেক্টস কাজ করতে অদ্ভুত।
হাশরকেটসিন্ট্যাক্স

7

আমি এই ফাংশনটি নিজের জন্য লিখেছি (বৃহস্পতিতে) এবং এটি ইন্দ্রাফোয়ের জবাব দ্বারা অনুপ্রাণিত হয়েছিল । এটি সমস্ত স্তর আউটপুট স্বয়ংক্রিয়ভাবে প্লট করবে। আপনার চিত্রগুলির অবশ্যই একটি (x, y, 1) আকার থাকতে হবে যেখানে 1 টি 1 টি চ্যানেল। আপনি কেবল প্লট করতে প্লট_লেয়ার_আউটপুট (...) কল করেছেন।

%matplotlib inline
import matplotlib.pyplot as plt
from keras import backend as K

def get_layer_outputs():
    test_image = YOUR IMAGE GOES HERE!!!
    outputs    = [layer.output for layer in model.layers]          # all layer outputs
    comp_graph = [K.function([model.input]+ [K.learning_phase()], [output]) for output in outputs]  # evaluation functions

    # Testing
    layer_outputs_list = [op([test_image, 1.]) for op in comp_graph]
    layer_outputs = []

    for layer_output in layer_outputs_list:
        print(layer_output[0][0].shape, end='\n-------------------\n')
        layer_outputs.append(layer_output[0][0])

    return layer_outputs

def plot_layer_outputs(layer_number):    
    layer_outputs = get_layer_outputs()

    x_max = layer_outputs[layer_number].shape[0]
    y_max = layer_outputs[layer_number].shape[1]
    n     = layer_outputs[layer_number].shape[2]

    L = []
    for i in range(n):
        L.append(np.zeros((x_max, y_max)))

    for i in range(n):
        for x in range(x_max):
            for y in range(y_max):
                L[i][x][y] = layer_outputs[layer_number][x][y][i]


    for img in L:
        plt.figure()
        plt.imshow(img, interpolation='nearest')

যদি মডেলটির বেশ কয়েকটি ইনপুট থাকে? ইনপুটগুলি কীভাবে নির্দিষ্ট করবেন?
আন্তোনিও সেস্তো

এই লাইনে: স্তর_ আউটপুট_লিস্ট = [ওপ ([টেস্ট_মেজ, ১]])। 1. কি 0 হওয়া দরকার? মনে হচ্ছে 1 টি প্রশিক্ষণের জন্য এবং 0 টি পরীক্ষার জন্য? তাই না?
কঙ্গসিয়া

এটি আমার জন্য কাজ করছে না। আমি একটি রঙিন চিত্র ব্যবহার করেছি এবং এটি আমাকে ত্রুটি দিচ্ছে: অবৈধঅর্গুমেন্টের ত্রুটি: ইনপুট_2: 0 উভয়ই খাওয়ানো এবং আনতে সক্ষম।
বৈভব কে

5

থেকে: https://github.com / ফিলিপাইরেমি / keras-visualize- activations/ blob/ master/ read_activations.py

import keras.backend as K

def get_activations(model, model_inputs, print_shape_only=False, layer_name=None):
    print('----- activations -----')
    activations = []
    inp = model.input

    model_multi_inputs_cond = True
    if not isinstance(inp, list):
        # only one input! let's wrap it in a list.
        inp = [inp]
        model_multi_inputs_cond = False

    outputs = [layer.output for layer in model.layers if
               layer.name == layer_name or layer_name is None]  # all layer outputs

    funcs = [K.function(inp + [K.learning_phase()], [out]) for out in outputs]  # evaluation functions

    if model_multi_inputs_cond:
        list_inputs = []
        list_inputs.extend(model_inputs)
        list_inputs.append(0.)
    else:
        list_inputs = [model_inputs, 0.]

    # Learning phase. 0 = Test mode (no dropout or batch normalization)
    # layer_outputs = [func([model_inputs, 0.])[0] for func in funcs]
    layer_outputs = [func(list_inputs)[0] for func in funcs]
    for layer_activations in layer_outputs:
        activations.append(layer_activations)
        if print_shape_only:
            print(layer_activations.shape)
        else:
            print(layer_activations)
    return activations

লিঙ্কটি হ্রাস করা হয়েছে।
সা Saeedদ


5

@ ম্যাথটিকের মন্তব্যে উল্লিখিত ইস্যুটির জন্য সংশোধন করার জন্য @ ইন্দ্রাফোরিওয়ের উত্তরটিতে এটি একটি মন্তব্য হিসাবে (তবে পর্যাপ্ত পরিমাণে রেপ নেই) add InvalidArgumentError: input_X:Y is both fed and fetched.ব্যতিক্রম এড়াতে , কেবল লাইনটি প্রতিস্থাপন করুনoutputs = [layer.output for layer in model.layers] সঙ্গে outputs = [layer.output for layer in model.layers][1:], অর্থাত্

ইন্দ্রাফোরিয়ের ন্যূনতম কাজের উদাহরণটি রূপান্তর করা:

from keras import backend as K 
inp = model.input                                           # input placeholder
outputs = [layer.output for layer in model.layers][1:]        # all layer outputs except first (input) layer
functor = K.function([inp, K.learning_phase()], outputs )   # evaluation function

# Testing
test = np.random.random(input_shape)[np.newaxis,...]
layer_outs = functor([test, 1.])
print layer_outs

PS আমার প্রচেষ্টা যেমন outputs = [layer.output for layer in model.layers[1:]]কাজ করে না এমন চেষ্টা করার চেষ্টা করে ।


1
এটা ঠিক সঠিক নয়। এটি কেবলমাত্র যদি ইনপুট স্তরটি প্রথম সংজ্ঞায়িত হয়।
এমপিজোস দিমিত্রিস

ধন্যবাদ, এটি আমার পক্ষে কাজ করেছে এবং এমপিজসের মন্তব্যের ভিত্তিতে আমি কেন বুঝতে পেরেছি তা পরীক্ষা করতে চাই: আমার মডেলটি মাত্র 3 স্তর (শব্দ এম্বেডিংস - বিএলএসটিএম - সিআরএফ), সুতরাং আমি অনুমান করি যে স্তরটি [0] বাদ দিতে হয়েছে কারণ ঠিক এম্বেডিংগুলি এবং একটি অ্যাক্টিভেশন থাকা উচিত নয়, তাই না?
কেমুনরো

@ এমপিজোস দিমিত্রিস হ্যাঁ এটি সঠিক, তবে @ ইন্দ্রাফারফ্যুই (যা আমি সংশোধন করছিলাম) প্রদত্ত উদাহরণে, এটি ছিল। @ কে মুনরো যদি আমি সঠিকভাবে বুঝতে পারি তবে আপনার প্রথম স্তরটির আউটপুট সম্পর্কে আপনি যত্ন নেওয়ার কারণটি হ'ল এটি কেবল এম্বেডিং শব্দের আউটপুট যা কেবল শব্দটিকে নিজেকে সেন্সর আকারে এম্বেড করে রাখা (যা কেবলমাত্র আপনার kerasমডেলের "নেটওয়ার্ক" অংশে ইনপুট )। আপনার শব্দ এম্বেডিংস স্তরটি এখানে সরবরাহিত উদাহরণের ইনপুট স্তরের সমতুল্য।
কামকম

3

ধরে নিচ্ছি আপনার কাছে:

1- কেরাস প্রাক প্রশিক্ষিত model

2- xচিত্র বা চিত্রের সেট হিসাবে ইনপুট । চিত্রের রেজোলিউশনটি ইনপুট স্তরের মাত্রার সাথে সামঞ্জস্যপূর্ণ হওয়া উচিত। উদাহরণস্বরূপ 80 * 80 * 3 3-চ্যানেল (আরজিবি) চিত্রের জন্য ।

3- layerঅ্যাক্টিভেশন পেতে আউটপুট নাম । উদাহরণস্বরূপ, "সমতল 2" স্তর। এটি layer_namesভেরিয়েবলের অন্তর্ভুক্ত হওয়া উচিত , প্রদত্ত স্তরগুলির নাম উপস্থাপন করে model

4- batch_sizeএকটি alচ্ছিক যুক্তি।

তারপরে আপনি কোনও প্রদত্ত ইনপুট এবং প্রাক প্রশিক্ষিতের জন্য get_activationআউটপুটটির সক্রিয়করণ পেতে সহজেই ফাংশনটি ব্যবহার করতে পারেন :layerxmodel

import six
import numpy as np
import keras.backend as k
from numpy import float32
def get_activations(x, model, layer, batch_size=128):
"""
Return the output of the specified layer for input `x`. `layer` is specified by layer index (between 0 and
`nb_layers - 1`) or by name. The number of layers can be determined by counting the results returned by
calling `layer_names`.
:param x: Input for computing the activations.
:type x: `np.ndarray`. Example: x.shape = (80, 80, 3)
:param model: pre-trained Keras model. Including weights.
:type model: keras.engine.sequential.Sequential. Example: model.input_shape = (None, 80, 80, 3)
:param layer: Layer for computing the activations
:type layer: `int` or `str`. Example: layer = 'flatten_2'
:param batch_size: Size of batches.
:type batch_size: `int`
:return: The output of `layer`, where the first dimension is the batch size corresponding to `x`.
:rtype: `np.ndarray`. Example: activations.shape = (1, 2000)
"""

    layer_names = [layer.name for layer in model.layers]
    if isinstance(layer, six.string_types):
        if layer not in layer_names:
            raise ValueError('Layer name %s is not part of the graph.' % layer)
        layer_name = layer
    elif isinstance(layer, int):
        if layer < 0 or layer >= len(layer_names):
            raise ValueError('Layer index %d is outside of range (0 to %d included).'
                             % (layer, len(layer_names) - 1))
        layer_name = layer_names[layer]
    else:
        raise TypeError('Layer must be of type `str` or `int`.')

    layer_output = model.get_layer(layer_name).output
    layer_input = model.input
    output_func = k.function([layer_input], [layer_output])

    # Apply preprocessing
    if x.shape == k.int_shape(model.input)[1:]:
        x_preproc = np.expand_dims(x, 0)
    else:
        x_preproc = x
    assert len(x_preproc.shape) == 4

    # Determine shape of expected output and prepare array
    output_shape = output_func([x_preproc[0][None, ...]])[0].shape
    activations = np.zeros((x_preproc.shape[0],) + output_shape[1:], dtype=float32)

    # Get activations with batching
    for batch_index in range(int(np.ceil(x_preproc.shape[0] / float(batch_size)))):
        begin, end = batch_index * batch_size, min((batch_index + 1) * batch_size, x_preproc.shape[0])
        activations[begin:end] = output_func([x_preproc[begin:end]])[0]

    return activations

2

যদি আপনার নিম্নলিখিতগুলির মধ্যে একটি থাকে:

  • ত্রুটি: InvalidArgumentError: input_X:Y is both fed and fetched
  • একাধিক ইনপুট ক্ষেত্রে

আপনাকে নিম্নলিখিত পরিবর্তনগুলি করতে হবে:

  • outputsচলক ইনপুট স্তর জন্য ফিল্টার আউট যোগ করুন
  • উপর minnor পরিবর্তন functorsলুপ

সর্বনিম্ন উদাহরণ:

from keras.engine.input_layer import InputLayer
inp = model.input
outputs = [layer.output for layer in model.layers if not isinstance(layer, InputLayer)]
functors = [K.function(inp + [K.learning_phase()], [x]) for x in outputs]
layer_outputs = [fun([x1, x2, xn, 1]) for fun in functors]

বলতে কী বোঝায় [x1, x2, xn, 1]? আমার এক্স 1 সংজ্ঞায়িত করা হয়নি এবং আমি বুঝতে চাই যে আপনি সেখানে কী সংজ্ঞা দিচ্ছেন।
হ্যাশরকেটসিন্ট্যাক্স

@ হ্যাশরকেটসাইন্টাক্স x1এবং x2এটি মডেলের ইনপুট। যেমনটি বলা হয়েছে যে আপনার মডেলটিতে আপনি 2 ইনপুট পেয়েছেন।
এমপিজোস দিমিত্রিস

1

ঠিক আছে, অন্যান্য উত্তরগুলি খুব সম্পূর্ণ, তবে আকারগুলি "পেতে" না পারার জন্য "দেখার" একটি খুব প্রাথমিক উপায় রয়েছে।

শুধু একটি model.summary()। এটি সমস্ত স্তর এবং তাদের আউটপুট আকার মুদ্রণ করবে। "কিছুই নয়" মানগুলি পরিবর্তনশীল মাত্রা নির্দেশ করবে এবং প্রথম মাত্রা হবে ব্যাচের আকার।


এটি স্তরটির আউটপুট সম্পর্কে (বেস স্তরকে দেওয়া ইনপুটগুলি) স্তরটি নয়।
ম্যাথটিক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.