2017-02-08 2 views
1

나는 텐서 흐름에 대해 PIL을 사용하여 이진화 된 지문 이미지를 배우고 싶습니다. 2 진수 이미지를 배우려고하므로 모양이 올바르지 않습니다.(수정) Tensorflow tflearn 이진 이미지 학습 질문

from __future__ import division, print_function, absolute_import 
import pickle 
import numpy as np 
from PIL import Image 
import tflearn 
import tensorflow as tf 
from tflearn.layers.core import input_data, dropout, fully_connected 
from tflearn.layers.conv import conv_2d, max_pool_2d 
from tflearn.layers.estimator import regression 


def load_image(img_path): 
    img = Image.open(img_path) 

    return img 


def resize_image(in_image, new_width, new_height, out_image=None, 
       resize_mode=Image.ANTIALIAS): 
    img = in_image.resize((new_width, new_height), resize_mode) 

    if out_image: 
     img.save(out_image) 

    return img 


def pil_to_nparray(pil_image): 
    pil_image.load() 

    return np.asarray(pil_image, dtype="float32") 


def binarization(in_img, threshold): 
    im = in_img.convert('L') 
    for i in range(im.size[0]): 
     for j in range(im.size[1]): 
      if im.getpixel((i,j)) > threshold: 
       im.putpixel((i,j), 255) 
      else: 
       im.putpixel((i,j), 0) 
    return im.convert('F') 


def load_data(datafile, num_clss, save=True, save_path='dataset.pkl'): 
    train_list = open(datafile,'r') 
    labels = [] 
    images = [] 
    for line in train_list: 
     tmp = line.strip().split(' ') 
     fpath = tmp[0] 
     print(fpath) 
     img = load_image(fpath) 
     img = binarization(img, 128) 
     img = resize_image(img, 224, 224) 
     np_img = pil_to_nparray(img) 
     images.append(np_img) 

     index = int(tmp[1]) 
     label = np.zeros(num_clss) 
     label[index] = 1 
     labels.append(label) 
    if save: 
     pickle.dump((images, labels), open(save_path, 'wb')) 

    return images, labels 


def load_from_pkl(dataset_file): 
    X, Y = pickle.load(open(dataset_file, 'rb')) 
    return X, Y 


def create_vggnet(num_classes): 
    # Building 'VGGNet' 
    network = input_data(shape=[None, 224, 224, 3], name='input') 
    network = conv_2d(network, 64, filter_size=3, strides=1, activation='relu') 
    network = conv_2d(network, 64, filter_size=3, strides=1, activation='relu') 
    network = max_pool_2d(network, kernel_size=2, strides=2) 
    network = conv_2d(network, 128, filter_size=3, strides=1, activation='relu') 
    network = conv_2d(network, 128, filter_size=3, strides=1, activation='relu') 
    network = max_pool_2d(network, 2, strides=2) 

    network = conv_2d(network, 256, filter_size=3, strides=1, activation='relu') 
    network = conv_2d(network, 256, filter_size=3, strides=1, activation='relu') 
    network = conv_2d(network, 256, filter_size=3, strides=1, activation='relu') 
    network = max_pool_2d(network, kernel_size=2, strides=2) 

    network = conv_2d(network, 512, filter_size=3, strides=1, activation='relu') 
    network = conv_2d(network, 512, filter_size=3, strides=1, activation='relu') 
    network = conv_2d(network, 512, filter_size=3, strides=1, activation='relu') 
    network = max_pool_2d(network, kernel_size=2, strides=2) 

    network = conv_2d(network, 512, filter_size=3, strides=1, activation='relu') 
    network = conv_2d(network, 512, filter_size=3, strides=1, activation='relu') 
    network = conv_2d(network, 512, filter_size=3, strides=1, activation='relu') 
    network = max_pool_2d(network, kernel_size=2, strides=2) 

    network = fully_connected(network, 4096, activation='relu') 
    network = dropout(network, 0.5) 
    network = fully_connected(network, 4096, activation='relu') 
    network = dropout(network, 0.5) 
    network = fully_connected(network, num_classes, activation='softmax') 

    network = regression(network, optimizer='adam', loss='categorical_crossentropy', 
         learning_rate=0.001) 

    return network 


def train(network, X, Y): 
    # Trainingeed data dictionary, with placeholders as keys, and data as values. 
    model = tflearn.DNN(network, checkpoint_path='model_vgg', 
         max_checkpoints=1, tensorboard_verbose=2, tensorboard_dir='output') 
    model.fit(X, Y, n_epoch=100, validation_set=0.1, shuffle=True, show_metric=True, 
       batch_size=64, snapshot_step=200, snapshot_epoch=False, run_id='vgg_fingerprint') 
    model.save('model_save.model') 


def predict(network, modelfile, images): 
    model = tflearn.DNN(network) 
    model.load(modelfile) 

    return model.predict(images) 


if __name__ == '__main__': 
    #image, label = load_data('train.txt', 5) 
    X, Y = load_from_pkl('dataset.pkl') 
    net = create_vggnet(5) 
    train(net, X, Y) 

치수가 바뀌는 재구성을 사용하여 시도했습니다. 그러나 다음 오류가 반복됩니다.

오류는 다음과 같습니다. ValueError : Tensor u'input/X : 0 '에 모양 (?, 224, 224, 3)이있는 모양 값 (64,224,224)을 입력 할 수 없습니다.

무엇이 문제입니까?

+0

큰 모델이고 절인 된 데이터에 의존하는 것처럼 보입니다. 당신은 함께 [최소한과 완전한 문제의 예]를 시험해 볼 수 있습니까? (http://stackoverflow.com/help/mcve)? –

+0

예를 게시했습니다. –

답변

0

입력 모양이 문제입니다. 입력 레이어와 일치하지 않습니다.

은 입력 층 create_vggnet()에 정의되어

def create_vggnet(num_classes): 
    # Building 'VGGNet' 
    network = input_data(shape=[None, 224, 224, 3], name='input') 

그래서 예상 None (==있는) 시간 (224, 224, 3), 즉, 224x224 X RGB (3 개 채널)이다. 그리고 당신은 64 (당신의 배치 사이즈) 배 224x224를 통과합니다. RGB로 이미지를 확장 -

1) (아마 더 낭비) :

두 가지 수정 사항이 있습니다.

따라서 이미지를 'L' (밝기, 즉 회색조)로 변환 한 다음 이진화하면 RGB로 먼저 변환하십시오.

def binarization(in_img, threshold): 
    im = in_img.convert('L') 
    for i in range(im.size[0]): 
     for j in range(im.size[1]): 
      if im.getpixel((i, j)) > threshold: 
       im.putpixel((i, j), 255) 
      else: 
       im.putpixel((i, j), 0) 
    return im.convert('RGB').convert('F') 

2) (낭비 덜하지만, 당신은 당신의 네트워크를 변경하고 조금 (바로 입력 층) - 그래서 수 : 그럼 당신은 'F'

로 변환 할 수 있습니다 (http://effbot.org/imagingbook/image.htmHow do I save a mode 'F' image? (Python/PIL) 참조) 논쟁의 여지가있다, 이것은 "더 이상 VGG 16이 아니다.") 입력 레이어를 1 채널로 변경할 수 있습니다.

def create_vggnet(num_classes): 
    # Building 'VGGNet' 
    network = input_data(shape=[None, 224, 224, 1], name='input') 

불행하게도, shape=[None, 224, 224]는 (오류가 "텐서는 4D 할 필요"에 대해 뭔가입니다) 작동하지 않습니다. 그래서 우리는 하나의 입력 값에 대해 (224, 224, 1) 모양을가집니다.

def pil_to_nparray(pil_image): 
    pil_image.load() 

    return np.expand_dims(np.asarray(pil_image, dtype="float32"), 2) 

또는 (어쩌면 더 나은) :

def pil_to_nparray(pil_image): 
    pil_image.load() 

    return np.asarray(pil_image, dtype="float32").reshape((224, 224, 1)) 

이 (후자의 버전이 정확히 무엇을보다 직접적으로 알고 보인다

그래서 당신은 이미지가 여분의 차원을 가지고해야 does) 그러나 이것은 입력 이미지가 224x224 인 경우에만 작동하며, expand_dims은 모든 크기에 대해 항상 추가 치수를 추가합니다.

+0

해결되었습니다. 답변 주셔서 감사합니다. –

관련 문제