Unverified Commit 62948177 authored by Karl Leswing's avatar Karl Leswing Committed by GitHub
Browse files

Merge pull request #1334 from pvskand/master

[WIP] Resnet 50
parents 214f2e92 33ca35b2
Loading
Loading
Loading
Loading
+163 −0
Original line number Diff line number Diff line
"""
ResNet-50 implementation
Deep Residual Learning for Image Recognition,
Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun

https://arxiv.org/abs/1512.03385

"""
import tensorflow as tf
import deepchem as dc
from deepchem.models import Sequential
from deepchem.models.tensorgraph.layers import Conv2D, MaxPool2D, Conv2DTranspose, Concat, Feature, Label, BatchNorm
from deepchem.models.tensorgraph.layers import SoftMaxCrossEntropy, ReduceMean, SoftMax, ReLU, Add, Flatten, Dense
from deepchem.models import TensorGraph


class ResNet50(TensorGraph):
  """
        ResNet50 architecture implementation.
        Parameters
        ----------
        img_rows : int
         number of rows of the image.
        img_cols: int
         number of columns of the image
        weights: string
         if "imagenet" - weights are initialized with the pretrained values.
        classes: int
         specifies number of classes
    """

  def identity_block(self, input, kernel_size, filters):
    filters1, filters2, filters3 = filters

    output = Conv2D(
        num_outputs=filters1,
        kernel_size=1,
        activation='linear',
        padding='same',
        in_layers=[input])
    output = BatchNorm(in_layers=[output])
    output = ReLU(output)

    output = Conv2D(
        num_outputs=filters2,
        kernel_size=kernel_size,
        activation='linear',
        padding='same',
        in_layers=[input])
    output = BatchNorm(in_layers=[output])
    output = ReLU(output)

    output = Conv2D(
        num_outputs=filters3,
        kernel_size=1,
        activation='linear',
        padding='same',
        in_layers=[input])
    output = BatchNorm(in_layers=[output])

    output = Add(in_layers=[output, input])
    output = ReLU(output)

    return output

  def conv_block(self, input, kernel_size, filters, strides=2):
    filters1, filters2, filters3 = filters

    output = Conv2D(
        num_outputs=filters1,
        kernel_size=1,
        stride=strides,
        activation='linear',
        padding='same',
        in_layers=[input])
    output = BatchNorm(in_layers=[output])
    output = ReLU(output)

    output = Conv2D(
        num_outputs=filters2,
        kernel_size=kernel_size,
        activation='linear',
        padding='same',
        in_layers=[output])
    output = BatchNorm(in_layers=[output])
    output = ReLU(output)

    output = Conv2D(
        num_outputs=filters3,
        kernel_size=1,
        activation='linear',
        padding='same',
        in_layers=[output])
    output = BatchNorm(in_layers=[output])

    shortcut = Conv2D(
        num_outputs=filters3,
        kernel_size=1,
        stride=strides,
        activation='linear',
        padding='same',
        in_layers=[input])
    shortcut = BatchNorm(in_layers=[shortcut])
    output = Add(in_layers=[shortcut, output])
    output = ReLU(output)

    return output

  def __init__(self,
               img_rows=224,
               img_cols=224,
               weights="imagenet",
               classes=1000,
               **kwargs):
    super(ResNet50, self).__init__(use_queue=False, **kwargs)
    self.img_cols = img_cols
    self.img_rows = img_rows
    self.weights = weights
    self.classes = classes

    input = Feature(shape=(None, self.img_rows, self.img_cols, 3))
    labels = Label(shape=(None, self.classes))

    conv1 = Conv2D(
        num_outputs=64,
        kernel_size=7,
        stride=2,
        activation='linear',
        padding='same',
        in_layers=[input])
    bn1 = BatchNorm(in_layers=[conv1])
    ac1 = ReLU(bn1)
    pool1 = MaxPool2D(ksize=[1, 3, 3, 1], in_layers=[bn1])

    cb1 = self.conv_block(pool1, 3, [64, 64, 256], 1)
    id1 = self.identity_block(cb1, 3, [64, 64, 256])
    id1 = self.identity_block(id1, 3, [64, 64, 256])

    cb2 = self.conv_block(id1, 3, [128, 128, 512])
    id2 = self.identity_block(cb2, 3, [128, 128, 512])
    id2 = self.identity_block(id2, 3, [128, 128, 512])
    id2 = self.identity_block(id2, 3, [128, 128, 512])

    cb3 = self.conv_block(id2, 3, [256, 256, 1024])
    id3 = self.identity_block(cb3, 3, [256, 256, 1024])
    id3 = self.identity_block(id3, 3, [256, 256, 1024])
    id3 = self.identity_block(id3, 3, [256, 256, 1024])
    id3 = self.identity_block(cb3, 3, [256, 256, 1024])
    id3 = self.identity_block(id3, 3, [256, 256, 1024])

    cb4 = self.conv_block(id3, 3, [512, 512, 2048])
    id4 = self.identity_block(cb4, 3, [512, 512, 2048])
    id4 = self.identity_block(id4, 3, [512, 512, 2048])

    pool2 = MaxPool2D(ksize=[1, 7, 7, 1], in_layers=[id4])

    flatten = Flatten(in_layers=[pool2])
    dense = Dense(classes, in_layers=[flatten])

    loss = SoftMaxCrossEntropy(in_layers=[labels, dense])
    loss = ReduceMean(in_layers=[loss])
    self.set_loss(loss)
    self.add_output(dense)
+45 −0
Original line number Diff line number Diff line
import deepchem
import numpy as np
import tensorflow as tf
import unittest
from deepchem.models.tensorgraph.models import resnet50
from deepchem.models.tensorgraph import layers


class TestResNet50(unittest.TestCase):

  def test_resnet50(self):
    resnet = deepchem.models.tensorgraph.models.resnet50.ResNet50(
        learning_rate=0.003,
        img_rows=128,
        img_cols=128,
        model_dir='./resnet50/')

    # Prepare Training Data
    data = np.ones((1, 128, 128, 3))
    position = np.array([1])
    labels = np.zeros((1, resnet.classes))
    labels[np.arange(1), position] = 1
    train = deepchem.data.NumpyDataset(data, labels)
    # Train the model
    resnet.fit(train, nb_epochs=0)
    resnet.save()
    # Prepare the Testing data
    test_data = np.ones((2, 128, 128, 3))
    test = deepchem.data.NumpyDataset(test_data)
    # predict
    predictions = resnet.predict(test)
    # check output shape
    self.assertEqual(predictions.shape, (2, 1000))

    # new object of ResNet to test if loading the model results in same predictions
    resnet_new = deepchem.models.tensorgraph.models.resnet50.ResNet50(
        learning_rate=0.003,
        img_rows=128,
        img_cols=128,
        model_dir='./resnet50/')
    resnet_new.load_from_dir('./resnet50/')
    resnet_new.restore()
    predictions_new = resnet_new.predict(test)

    self.assertTrue(np.all(predictions == predictions_new))