# Siamese network
Siamese network takes two inputs that are processed by two network that have the same neural network architecture (same structure and weights). The Eucledian distance between the output of these vectors is used to compare how similar the two images are.
```mermaid
graph TD;
a[Input a] --> b
subgraph
b[Neural Network] --> c[Output Vector 1];
end
x[Input b] --> y
subgraph
y[Neural Network] --> z[Output Vector 2];
end
c --> d[Eucledian Distance]
z -->d
d --> e[Output]
```
### Code:
Base Neural network
```python
def initialize_base_network():
input = Input(shape=(28,28))
x = Flatten()(input)
x = Dense(128, activation='relu')(x)
x = Dropout(0.1)(x)
x = Dense(128, activation='relu')(x)
x = Dropout(0.1)(x)
x = Dense(128, activation='relu')(x)
return Model(inputs=input, outputs=x)
```
Reusing the base network
```python
base_network = initialize_base_network()
input_a = Input(shape=(28,28))
input_b = Input(shape=(28,28))
vect_output_a = base_network(input_a)
vect_output_b = base_network(input_b)
def euclidean_dist(vects):
x, y = vects
sumsquare = K.sum(K.square(x - y), axis=1, keepdims=True)
return K.sqrt(K.maximum(sum_square, K.epsilon()))
def eucl_dist_output_shape(shapes):
shape1, shape2 = shapes
return(shape1[0], 1)
output = Lambda(euclidian_distance, output=eucl_dist_output_shape)([vect_output_a, vect_output_b])
model = Model(inputs=[input_a, input_b], outputs=output)
rms = RMSprop()
model.compile(loss=contrastive_loss, optimizer=rms)
```
Train the Model
```python
model.fit(
[tr_pairis[:,0], tr_pairs[:,1]],
tr_y,
epochs=20,
batch_size=128,
validation_data=([ts_pairs[:,0], ts_pairs[:,1]], ts_y)
)
```