Rakib
Rakib

Reputation: 7625

How to use bias for custom layer in keras

I created a custom layer, but not sure how can I use and train bias weights for this layer.

from keras import backend as K
from keras.engine.topology import Layer
import numpy as np
import tensorflow as tf

class MyLayer(Layer):

    def __init__(self, output_dim, **kwargs):
        self.output_dim = output_dim
        super(MyLayer, self).__init__(**kwargs)

    def build(self, input_shape):
        self.kernel = self.add_weight(name='kernel', 
                                      shape=(input_shape[1], self.output_dim),
                                      initializer='he_normal',
                                      trainable=True)
        super(MyLayer, self).build(input_shape)

    def call(self, x):
        ep = K.constant(value= 10e-5, shape=(1,513))
        v = K.dot(x, self.kernel)
        out = K.switch((v - ep)>0,  v,  - (ep)/(v-1-ep))
        return out


    def compute_output_shape(self, input_shape):
        return (input_shape[0], self.output_dim)

Upvotes: 1

Views: 3253

Answers (2)

Cyril Cao
Cyril Cao

Reputation: 13

Good answer from Daniel. However, the shape of the bias should be written as shape=(self.output_dim,), with a extra comma before the closing parenthesis, or you'll be faced with the error TypeError: 'int' object is not iterable.

Reference (Dense layer implementation by keras team):

def build(self, input_shape):
    assert len(input_shape) >= 2
    input_dim = input_shape[-1]

    self.kernel = self.add_weight(shape=(input_dim, self.units),
                                  initializer=self.kernel_initializer,
                                  name='kernel',
                                  regularizer=self.kernel_regularizer,
                                  constraint=self.kernel_constraint)
    if self.use_bias:
        self.bias = self.add_weight(shape=(self.units,),
                                    initializer=self.bias_initializer,
                                    name='bias',
                                    regularizer=self.bias_regularizer,
                                    constraint=self.bias_constraint)
    else:
        self.bias = None
    self.input_spec = InputSpec(min_ndim=2, axes={-1: input_dim})
    self.built = True

Upvotes: 0

Daniel Möller
Daniel Möller

Reputation: 86600

Exactly the same way you used regular weights....

def build(self, input_shape):
    self.kernel = self.add_weight(name='kernel', 
                                  shape=(input_shape[1], self.output_dim),
                                  initializer='he_normal',
                                  trainable=True)
    self.bias = self.add_weight(name='bias',
                                shape=(self.output_dim),
                                initializer='zeros',
                                trainable=True)
    super(MyLayer, self).build(input_shape)

def call(self, x):
    ep = K.constant(value= 10e-5, shape=(1,513))
    v = K.dot(x, self.kernel)   #maybe add bias here?
    out = K.switch((v - ep)>0,  v,  - (ep)/(v-1-ep))
    return out + self.bias

Upvotes: 1

Related Questions