मैं keras एप्लिकेशन से VGG19 मॉडल का उपयोग कर रहा हूं। मैं उम्मीद कर रहा था कि छवि को [-1, 1] तक बढ़ाया जाएगा, लेकिन इसके बजाय, ऐसा लगता है कि preprocess_input कुछ और कर रहा है।

इनपुट को प्रीप्रोसेस करने के लिए, मैं पहले छवि को लोड करने के लिए निम्नलिखित 2 पंक्तियों का उपयोग करता हूं और फिर इसे स्केल करता हूं:

from keras.preprocessing import image
from keras.applications.vgg19 import preprocess_input

img = image.load_img("./img.jpg", target_size=(256, 256))
img = preprocess_input(np.array(img))

print(img)
>>> array([[[151.061  , 138.22101, 131.32   ],
    ... ]]]

आउटपुट [०,२५५] अंतराल में प्रतीत होता है, हालांकि, मूल २५५ को १५१ (संभावित रूप से केंद्रित) के मूल्यों पर मैप किया गया था। वीजीजी को वास्तव में किस इनपुट की आवश्यकता होती है? मैंने सोचा कि यह स्रोत कोड (mode='tf' के लिए) को देखकर [-1,1] में होना चाहिए। क्या यह काफी लचीला है और मैं किसी भी प्रकार की स्केलिंग का उपयोग कर सकता हूं जो मैं चाहता हूं? (मैं मध्य स्तर की सुविधाओं को निकालने के लिए VGG का उपयोग कर रहा हूं - Conv4 ब्लॉक)।

जब मैं preprocess_input के स्रोत कोड को देखता हूं तो मैं देखता हूं:

...
    if mode == 'tf':
        x /= 127.5
        x -= 1.
        return x
...

जो बताता है कि टेंसरफ़्लो बैकएंड के लिए (जो कि केरस उपयोग कर रहा है), इसे [-1,1] तक बढ़ाया जाना चाहिए।

मुझे एक फ़ंक्शन restore_original_image_from_array() बनाने की ज़रूरत है जो img ले लेगा और उस मूल छवि का पुनर्निर्माण करेगा जिसे मैंने खिलाया था। समस्या यह है कि मुझे यकीन नहीं है कि VGG19 के लिए स्केलिंग कैसे होती है।

तो संक्षेप में मैं करना चाहूंगा:

img = image.load_img("./img.jpg", target_size=(256, 256))
scaled_img = preprocess_input(np.array(img))
restore_original_image_from_array(scaled_img) == np.array(img)
>>> True
3
GRS 5 मई 2019, 01:23

2 जवाब

सबसे बढ़िया उत्तर

preprocess_input फ़ंक्शन का "मोड" उस ढांचे पर निर्भर करता है जिस पर पहले से प्रशिक्षित नेटवर्क वज़न को प्रशिक्षित किया गया था। Keras में VGG19 नेटवर्क कैफ़े में मूल VGG19 मॉडल से वज़न का उपयोग करता है, और इस कारण से, preprocess_input में तर्क डिफ़ॉल्ट (mode='caffe') होना चाहिए। यह प्रश्न देखें: Keras VGG16 preprocess_input mode

अपने उद्देश्यों के लिए, preprocess_input फ़ंक्शन का उपयोग करें जो keras.applications.vgg19 में पाया जाता है और इसे वहां से रिवर्स इंजीनियर करता है।

मूल प्रीप्रोसेसिंग यहां पाई जाती है: https:/ /github.com/keras-team/keras-applications/blob/master/keras_applications/imagenet_utils.py#L21

इसमें शामिल है 1) छवि (छवियों) को आरजीबी से बीजीआर में परिवर्तित करना 2) छवि (ओं) से डेटासेट माध्य घटाना

मूल छवि को पुनर्स्थापित करने के लिए कोड यहां दिया गया है:

def restore_original_image_from_array(x, data_format='channels_first'):
    mean = [103.939, 116.779, 123.68]

    # Zero-center by mean pixel
    if data_format == 'channels_first':
        if x.ndim == 3:
            x[0, :, :] += mean[0]
            x[1, :, :] += mean[1]
            x[2, :, :] += mean[2]
        else:
            x[:, 0, :, :] += mean[0]
            x[:, 1, :, :] += mean[1]
            x[:, 2, :, :] += mean[2]
    else:
        x[..., 0] += mean[0]
        x[..., 1] += mean[1]
        x[..., 2] += mean[2]

    if data_format == 'channels_first':
        # 'BGR'->'RGB'
        if x.ndim == 3:
            x = x[::-1, ...]
        else:
            x = x[:, ::-1, ...]
    else:
        # 'BGR'->'RGB'
        x = x[..., ::-1]

    return x
3
Gabriel Ibagon 4 मई 2019, 23:38

वीजीजी नेटवर्क को छवि पर प्रशिक्षित किया जाता है और प्रत्येक चैनल को माध्य = [१०३.९३९, ११६.७७९, १२३.६८] और चैनल बीजीआर द्वारा सामान्यीकृत किया जाता है। इसके अलावा, चूंकि हमारी अनुकूलित छवि अपने मूल्यों को −∞ और ∞ के बीच कहीं भी ले जा सकती है, इसलिए हमें अपने मूल्यों को 0-255 रेंज के भीतर बनाए रखने के लिए क्लिप करना होगा।
संसाधित छवि को 'डीप्रोसेस' या उलटा संसाधित करने के लिए कोड यहां दिया गया है:

def deprocess_img(processed_img):
  x = processed_img.copy()
  if len(x.shape) == 4:
    x = np.squeeze(x, 0)
  assert len(x.shape) == 3, ("Input to deprocess image must be an image of "
                             "dimension [1, height, width, channel] or [height, width, channel]")
  if len(x.shape) != 3:
    raise ValueError("Invalid input to deprocessing image")
  
  # perform the inverse of the preprocessiing step
  x[:, :, 0] += 103.939
  x[:, :, 1] += 116.779
  x[:, :, 2] += 123.68
  x = x[:, :, ::-1]

  x = np.clip(x, 0, 255).astype('uint8')
  return x
0
Sanchit Vijay 27 जुलाई 2020, 17:28