胶囊网络中挤压函数Squash的实现(tensorflow和pytorch)

胶囊网络中挤压函数Squash的实现(tensorflow和pytorch)

写在前面

最近参加学校的一个比赛,与组内成员讨论了一番准备使用胶囊网络实现对街景交通标志的识别,我们找到的基本的源代码是tensorflow实现的,需要将其转换成pytorch的代码(工作量巨大,草【一种植物】)
本文就胶囊网络的挤压函数的转化进行说明,记录,一方面是为了让自己记住,另一方面也能为后来的同学们提供方法。
另外这篇文章也会记录一些Latex的输入公式,主要是用于我自己看的哈哈哈

向量的二范数

$\Vert  V \Vert_2$ = $\sqrt{x_1^2+x_2^2+...+x_n^2}$,其中$x_i\in V$

∥ V ∥ 2 \Vert V \Vert_2 V2 = x 1 2 + x 2 2 + . . . + x n 2 \sqrt{x_1^2+x_2^2+...+x_n^2} x12+x22+...+xn2 ,其中 x i ∈ V x_i\in V xiV
那么注意到其实向量二范数就是向量的模长,由各个元素的平方和开根号得到

挤压函数

$||\vec V_j^l||$=squash($||S_j^i||$)=$\frac{||S^l_j||^2}{1+||S^l_j||^2}\cdot\frac{S_j^l}{||S^l_j||^2}$

在文章中我们假设得到的向量是 ∣ ∣ S ∣ ∣ ||S|| ∣∣S∣∣,经过挤压后得到向量 ∣ ∣ V ∣ ∣ ||V|| ∣∣V∣∣
那么有以下公式:
∣ ∣ V ⃗ j l ∣ ∣ ||\vec V_j^l|| ∣∣V jl∣∣=squash( ∣ ∣ S j l ∣ ∣ ||S_j^l|| ∣∣Sjl∣∣)= ∣ ∣ S j l ∣ ∣ 2 2 1 + ∣ ∣ S j l ∣ ∣ 2 2 ⋅ S j l ∣ ∣ S j l ∣ ∣ 2 \frac{||S^l_j||^2_2}{1+||S^l_j||^2_2}\cdot\frac{S_j^l}{||S^l_j||_2} 1+∣∣Sjl22∣∣Sjl22∣∣Sjl2Sjl

挤压函数的实现

通过上面的公式我们知道,要想实现Squash函数,需要做平方和运算,开方运算。
tensorflow实现方式:

def squash(vector):#vector对应公式中的S
	'''
		tf.square:对输入变量的每个元素求平方
		tf.reduce_sum:第一个参数为待求和的向量,第二个参数为维度,第三个参数为是否改变输入向量的维度
	'''
	vector +=0.00001
	norm = tf.reduce_sum(tf.square(vector), -2, keep_dims=True)
	#这里的norm对应公式中S二范数的平方
	scalar = norm/(1+norm)/tf.sqrt(norm)
	V = scalar * vector#V对应公式中的V
	return V

pytorch实现方式

def squash(inputs, axis=-1):
	#这里的norm对应公式中S的二范数(跟上面的norm不一样)
	#torch.norm可以直接计算输入向量的范数,第二个参数为范数的类型,p=2为二范数
    norm = torch.norm(inputs, p=2, dim=axis, keepdim=True)
    scale = norm**2 / (1 + norm**2) /norm 
    V = scale * inputs
    return V
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作为一种开源的机器学习框架,TensorFlow被广泛应用于各种应用场景,其就包括胶囊网络胶囊网络是一种用于图像分析和分类的新型神经网络结构,不仅具有较高的准确率,而且能够使用更少的架构参数来实现。下面就让我们来看看如何使用TensorFlow实现胶囊网络胶囊网络的核心组件是胶囊,一种用于代替传统神经网络的全连接层的基础组件。胶囊由一个向量(被称为胶囊结果)和一个学习到的矩阵(被称为转换矩阵)组成。TensorFlow胶囊网络可以使用tf.contrib.capsule的库来实现,该库包括以下几个组件: 1. Capsule层:用于实现胶囊网络的胶囊层,该层包括若干个胶囊单元,每个单元输出一个向量。 2. Route层:用于将胶囊层的输出转换为下一层输入的加权和,该层包括两个输入——胶囊层的输出和前一层的输出。 3. Squash函数:用于将胶囊输出向量缩放到0和1之间,该函数可以使用一个简单的非线性函数实现。 4. Margin Loss:用于计算胶囊网络的损失函数,该损失函数包括预测误差和正则化项,可以使用标准的交叉熵损失函数实现。 一个简单的胶囊网络可以通过以下TensorFlow代码来实现: ``` python import tensorflow as tf import numpy as np class CapsuleLayer(object): def __init__(self, input_capsules, output_capsules, output_dim, routing_iterations): self.input_capsules = input_capsules self.output_capsules = output_capsules self.output_dim = output_dim self.routing_iterations = routing_iterations self.w = tf.Variable(tf.random_normal([output_capsules, input_capsules, output_dim, input_dim])) def __call__(self, input): input = tf.expand_dims(input, axis=2) input = tf.tile(input, [1, 1, self.output_capsules, 1, 1]) input = tf.transpose(input, perm=[0, 2, 1, 3, 4]) capsules = tf.matmul(self.w, input) b = tf.zeros([input.shape[0], self.output_capsules, self.input_capsules]) for i in range(self.routing_iterations): c = tf.nn.softmax(b, axis=1) s = tf.reduce_sum(tf.multiply(c, capsules), axis=2, keep_dims=True) v = self.squash(s) if i < self.routing_iterations - 1: b += tf.reduce_sum(tf.multiply(capsules, v), axis=3) return tf.squeeze(v, [1, 4]) def squash(self, vector): squared_norm = tf.reduce_sum(tf.square(vector), axis=-2, keep_dims=True) scaled = squared_norm / (1 + squared_norm) * vector return scaled / tf.sqrt(squared_norm + 1e-9) class RouteLayer(object): def __init__(self, input_dim, output_dim): self.input_dim = input_dim self.output_dim = output_dim self.w = tf.Variable(tf.random_normal([output_dim, input_dim])) def __call__(self, input): input = tf.reshape(input, [-1, self.input_dim]) output = tf.matmul(input, self.w, transpose_b=True) return output class Squash(object): def __call__(self, vector): squared_norm = tf.reduce_sum(tf.square(vector), axis=-2, keep_dims=True) scaled = squared_norm / (1 + squared_norm) * vector return scaled / tf.sqrt(squared_norm + 1e-9) class MarginLoss(object): def __init__(self, m_plus, m_minus, lambda_value): self.m_plus = m_plus self.m_minus = m_minus self.lambda_value = lambda_value def __call__(self, y_true, y_pred): L = y_true * tf.square(tf.maximum(0., self.m_plus - y_pred)) + \ self.lambda_value * (1 - y_true) * tf.square(tf.maximum(0., y_pred - self.m_minus)) return tf.reduce_mean(tf.reduce_sum(L, axis=1)) ``` 以上代码实现胶囊网络的四个核心组件(CapsuleLayer、RouteLayer、Squash和MarginLoss),其CapsuleLayer实现了胶囊层,RouteLayer实现了路由层,Squash实现了缩放函数,MarginLoss实现胶囊网络的损失函数。通过这些组件,可以在TensorFlow构建一个简单的胶囊网络。 需要注意的是,以上代码仅提供了一个简单的胶囊网络实现,实际应用可能涉及到更复杂的模型,需要根据具体场景进行修改和优化,以提高网络的性能和准确率。同时,由于TensorFlow是一种强大的机器学习框架,拥有庞大的社区和丰富的资源,因此在应用也可以参考社区的代码和文档,以快速实现和优化胶囊网络

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值