Kaggle 題目 Dogs vs。 Cats Redux: Kernels Edition

框架:Tensorflow(上層框架使用TF-slim)

問題描述:輸入圖片,判斷圖片中為貓還是狗。

實現方法:Fine-tune TF-slim中提供的VGG-19神經網路。

預訓練模型引數:

https://

github。com/tensorflow/m

odels/tree/master/research/slim

資料集:Dogs vs。 Cats Redux: Kernels Edition

程式碼:2012013382/Cat_or_dog-kaggle-vgg16-tensorflow

資料預處理

讀入資料將圖片整理為矩陣形式,將標籤整理為one_hot形式。注意VGG_19的輸入必須為[Batch_size, 224, 224, 3]。

from

__future__

import

absolute_import

from

__future__

import

division

from

__future__

import

print_function

import

numpy

as

np

from

scipy。misc

import

imread

imresize

from

os

import

walk

from

os。path

import

join

import

tensorflow

as

tf

def

read_images

path

classes

img_height

=

224

img_width

=

224

img_channels

=

3

):

filenames

=

walk

path

))

next

()[

2

num_files

=

len

filenames

images

=

np

zeros

((

num_files

img_height

img_width

img_channels

),

dtype

=

np

float32

labels

=

np

zeros

((

num_files

),

dtype

=

np

int32

for

i

filename

in

enumerate

filenames

):

img

=

imread

join

path

filename

))

#read train data

img

=

imresize

img

img_height

img_width

))

#resize image to 224x224

img

astype

np

float32

images

i

:,

:,

:]

=

img

labels

i

=

classes

index

filename

0

3

])

# Luckily both ‘cat’ and ‘dog’ have 3 characters

# Convert from [0, 255] -> [-0。5, 0。5] floats。

#images[i, :, :, :] = images[i, :, :, :] * (1。 / 255) - 0。5

one_hot_labels

=

np

zeros

((

num_files

len

classes

)))

if

i

%

1000

==

0

print

‘Load the

%d

image of 25000。’

%

i

))

for

i

in

range

num_files

):

one_hot_labels

i

labels

i

]]

=

1

return

images

one_hot_labels

#Read image function for kaggle test data

def

read_images_kaggle_result

path

img_height

=

224

img_width

=

224

img_channels

=

3

):

filenames

=

walk

path

))

next

()[

2

num_files

=

len

filenames

images

=

np

zeros

((

num_files

img_height

img_width

img_channels

),

dtype

=

np

float32

for

i

filename

in

enumerate

filenames

):

img

=

imread

join

path

filename

))

#read train data

img

=

imresize

img

img_height

img_width

))

#resize image to 224x224

img

astype

np

float32

images

int

filename

[:

-

4

])

-

1

:,

:,

:]

=

img

#images[int(filename[:-4]) - 1, :, :, :] = images[int(filename[:-4]) - 1, :, :, :] * (1。 / 255) - 0。5

if

i

%

1000

==

0

print

‘Load the

%d

image of 12500。’

%

i

))

return

images

Kaggle提供的訓練集中共有25000張圖片,取其中30%作為驗證集,用於調參;其他作為訓練集,用於訓練模型。TensorFlow有利用佇列讀取資料的方式,能夠高效從磁碟中讀取資料,具體可以參考其官方教程。這裡為了方便,我使用簡單的一次性讀取的方法將資料弄成一batch的形式,用於之後的輸入。

from

__future__

import

absolute_import

from

__future__

import

division

from

__future__

import

print_function

import

manage_images

import

numpy

as

np

IMG_CLASSES

=

‘cat’

‘dog’

DATA_DIR

=

‘data/’

TRAIN_DATA_PATH

=

‘data/train/’

TEST_DATA_PATH

=

‘data/test/’

IMG_HEIGHT

=

int

224

#image shape [224,224,3] to fit VGG_16 input shape。

IMG_WIDTH

=

int

224

IMG_CHANNELS

=

3

NUM_FILES_DATASET

=

25000

#data size 25000; train data size 17500; test data size 7500

VALIDATION_SET_FRACTION

=

0。3

#validation size properbility

NUM_TRAIN_EXAMPLES

=

int

((

1

-

VALIDATION_SET_FRACTION

*

NUM_FILES_DATASET

NUM_VALIDATION_EXAMPLES

=

int

((

VALIDATION_SET_FRACTION

*

NUM_FILES_DATASET

NUM_KAGGLE_TEST

=

12500

def

pre_processing

data_set

=

‘train’

batch_size

=

32

):

if

data_set

is

‘train’

images

labels

=

manage_images

read_images

TRAIN_DATA_PATH

IMG_CLASSES

IMG_HEIGHT

IMG_WIDTH

IMG_CHANNELS

#Substract mean value

train_mean

=

np

mean

images

axis

=

0

# Random sample

validation_images

=

[]

validation_labels

=

[]

train_images

=

[]

train_labels

=

[]

validation_size

=

int

VALIDATION_SET_FRACTION

*

len

images

))

idx

=

np

random

permutation

len

images

))

for

i

in

idx

if

i

<

validation_size

validation_images

append

images

i

-

train_mean

validation_labels

append

labels

i

])

else

train_images

append

images

i

-

train_mean

train_labels

append

labels

i

])

train_batch_num

=

NUM_TRAIN_EXAMPLES

//

batch_size

validation_batch_num

=

NUM_VALIDATION_EXAMPLES

//

batch_size

pointer

=

0

batch_train_images

=

[]

batch_train_labels

=

[]

batch_validation_images

=

[]

batch_validation_labels

=

[]

for

_

in

range

train_batch_num

):

batch_train_images

append

train_images

pointer

pointer

+

batch_size

])

batch_train_labels

append

train_labels

pointer

pointer

+

batch_size

])

pointer

=

pointer

+

batch_size

pointer

=

0

for

_

in

range

validation_batch_num

):

batch_validation_images

append

validation_images

pointer

pointer

+

batch_size

])

batch_validation_labels

append

validation_labels

pointer

pointer

+

batch_size

])

pointer

=

pointer

+

batch_size

batch_validation_set

=

{

‘images’

batch_validation_images

‘labels’

batch_validation_labels

}

batch_train_set

=

{

‘images’

batch_train_images

‘labels’

batch_train_labels

}

image_num

=

{

‘train’

NUM_TRAIN_EXAMPLES

‘validation’

NUM_VALIDATION_EXAMPLES

}

return

batch_train_set

batch_validation_set

image_num

elif

data_set

is

‘test’

images

=

manage_images

read_images_kaggle_result

TEST_DATA_PATH

IMG_HEIGHT

IMG_WIDTH

IMG_CHANNELS

#Substract mean

mean

=

np

mean

images

axis

=

0

images

=

images

-

mean

batch_test_images

=

[]

batch_num

=

NUM_KAGGLE_TEST

//

batch_size

pointer

=

0

for

_

in

range

batch_num

):

batch_test_images

append

images

pointer

pointer

+

batch_size

])

pointer

=

pointer

+

batch_size

batch_test_set

=

{

‘images’

batch_test_images

}

return

batch_test_set

訓練

from

__future__

import

absolute_import

from

__future__

import

division

from

__future__

import

print_function

import

numpy

as

np

import

time

import

data_processing

import

tensorflow

as

tf

import

tensorflow。contrib。slim

as

slim

import

tensorflow。contrib。slim。nets

as

nets

import

os

import

os。path

import

time

TRAIN_LOG_DIR

=

os

path

join

‘Log/train/’

time

strftime

‘%Y-%m-

%d

%H:%M:%S’

time

localtime

time

time

())))

TRAIN_CHECK_POINT

=

‘check_point/train_model。ckpt’

VALIDATION_LOG_DIR

=

‘Log/validation/’

VGG_19_MODEL_DIR

=

‘check_point/vgg_19。ckpt’

BATCH_SIZE

=

32

EPOCH

=

3

if

not

tf

gfile

Exists

TRAIN_LOG_DIR

):

tf

gfile

MakeDirs

TRAIN_LOG_DIR

if

not

tf

gfile

Exists

VALIDATION_LOG_DIR

):

tf

gfile

MakeDirs

VALIDATION_LOG_DIR

batch_train_set

batch_validation_set

images_num

=

data_processing

pre_processing

data_set

=

‘train’

batch_size

=

BATCH_SIZE

def

get_accuracy

logits

labels

):

correct_prediction

=

tf

equal

tf

argmax

logits

1

),

tf

argmax

labels

1

))

accuracy

=

tf

reduce_mean

tf

cast

correct_prediction

tf

float32

))

return

accuracy

with

tf

Graph

()

as_default

():

images

=

tf

placeholder

tf

float32

BATCH_SIZE

224

224

3

])

labels

=

tf

placeholder

tf

float32

BATCH_SIZE

len

data_processing

IMG_CLASSES

)])

keep_prob

=

tf

placeholder

tf

float32

with

slim

arg_scope

nets

vgg

vgg_arg_scope

()):

logits

_

=

nets

vgg

vgg_19

inputs

=

images

num_classes

=

2

dropout_keep_prob

=

keep_prob

is_training

=

True

variables_to_restore

=

slim

get_variables_to_restore

exclude

=

‘vgg_19/fc8’

])

restorer

=

tf

train

Saver

variables_to_restore

with

tf

name_scope

‘cross_entropy’

):

loss

=

tf

reduce_mean

tf

nn

softmax_cross_entropy_with_logits

logits

=

logits

labels

=

labels

))

tf

summary

scalar

‘cross_entropy’

loss

learning_rate

=

1e-4

optimizer

=

tf

train

AdamOptimizer

learning_rate

minimize

loss

with

tf

name_scope

‘accuracy’

):

accuracy

=

get_accuracy

logits

labels

tf

summary

scalar

‘accuracy’

accuracy

merged

=

tf

summary

merge_all

()

saver

=

tf

train

Saver

()

config

=

tf

ConfigProto

()

config

gpu_options

allow_growth

=

True

with

tf

Session

config

=

config

as

sess

train_writer

=

tf

summary

FileWriter

TRAIN_LOG_DIR

#train_writer。add_summary(sess。graph)

sess

run

tf

global_variables_initializer

())

sess

run

tf

local_variables_initializer

())

restorer

restore

sess

VGG_19_MODEL_DIR

step

=

0

for

ep

in

range

EPOCH

):

all_accuracy

=

0

all_loss

=

0

for

i

in

range

images_num

‘train’

//

BATCH_SIZE

):

_

accuracy_out

loss_out

summary

=

sess

run

([

optimizer

accuracy

loss

merged

],

feed_dict

=

{

images

batch_train_set

‘images’

][

i

],

\

labels

batch_train_set

‘labels’

][

i

],

keep_prob

0。5

})

train_writer

add_summary

summary

step

step

+=

1

all_accuracy

+=

accuracy_out

all_loss

+=

loss_out

if

i

%

10

==

0

print

“Epoch

%d

: Batch

%d

accuracy is

%。2f

; Batch loss is

%。5f

%

ep

+

1

i

accuracy_out

loss_out

))

print

“Epoch

%d

: Train accuracy is

%。2f

; Train loss is

%。5f

%

ep

+

1

all_accuracy

/

images_num

‘train’

//

BATCH_SIZE

),

all_loss

/

images_num

‘train’

//

BATCH_SIZE

)))

all_accuracy

=

0

all_loss

=

0

for

i

in

range

images_num

‘validation’

//

BATCH_SIZE

):

accuracy_out

loss_out

=

sess

run

([

accuracy

loss

],

feed_dict

=

{

images

batch_validation_set

‘images’

][

i

],

\

labels

batch_validation_set

‘labels’

][

i

],

keep_prob

1。0

})

all_accuracy

+=

accuracy_out

all_loss

+=

loss_out

print

“Epoch

%d

: Validation accuracy is

%。2f

; Validation loss is

%。5f

%

ep

+

1

all_accuracy

/

images_num

‘validation’

//

BATCH_SIZE

),

all_loss

/

images_num

‘validation’

//

BATCH_SIZE

)))

saver

save

sess

TRAIN_CHECK_POINT

global_step

=

ep

在我的實驗中驗證集上的準去率為97%。

測試

from

__future__

import

absolute_import

from

__future__

import

division

from

__future__

import

print_function

import

data_processing

import

tensorflow

as

tf

import

tensorflow。contrib。slim

as

slim

import

tensorflow。contrib。slim。nets

as

nets

import

csv

as

csv

CHECK_POINT_PATH

=

‘check_point/train_model。ckpt-2’

NUM_KAGGLE_TEST

=

12500

BATCH_SIZE

=

50

batch_test_set

=

data_processing

pre_processing

data_set

=

‘test’

batch_size

=

BATCH_SIZE

prediction_file

=

open

‘kaggle_result_file。csv’

‘wb’

prediction_file_object

=

csv

writer

prediction_file

prediction_file_object

writerow

([

‘id’

‘label’

])

with

tf

Graph

()

as_default

():

images

=

tf

placeholder

tf

float32

BATCH_SIZE

224

224

3

])

keep_prob

=

tf

placeholder

tf

float32

logits

_

=

nets

vgg

vgg_19

inputs

=

images

num_classes

=

2

dropout_keep_prob

=

keep_prob

is_training

=

False

variables_to_restore

=

slim

get_variables_to_restore

()

restorer

=

tf

train

Saver

variables_to_restore

pros

=

tf

nn

softmax

logits

config

=

tf

ConfigProto

()

config

gpu_options

allow_growth

=

True

with

tf

Session

config

=

config

as

sess

sess

run

tf

global_variables_initializer

())

sess

run

tf

local_variables_initializer

())

restorer

restore

sess

CHECK_POINT_PATH

for

i

in

range

NUM_KAGGLE_TEST

//

BATCH_SIZE

):

batch_pros

=

sess

run

pros

feed_dict

=

{

images

batch_test_set

‘images’

][

i

],

keep_prob

1。0

})

print

‘Batch

%d

of

%d

%

i

NUM_KAGGLE_TEST

//

BATCH_SIZE

))

for

j

in

range

BATCH_SIZE

):

temp

=

0。0

if

batch_pros

j

1

>

0。5

temp

=

0。995

else

temp

=

0。005

prediction_file_object

writerow

([

i

*

BATCH_SIZE

+

j

+

1

temp

])

prediction_file

close

()