计算PyTorch网络参数空间的距离

时间:2017-11-29 02:36:49

标签: python pytorch

我是PyTorch的新手。我想跟踪我的模型通过其优化的参数空间中的距离。这是我正在使用的代码。

class ParameterDiffer(object):
    def __init__(self, network):
        network_params = []
        for p in network.parameters():
            network_params.append(p.data.numpy())
        self.network_params = network_params

    def get_difference(self, network):
        total_diff = 0.0
        for i, p in enumerate(network.parameters()):
            p_np = p.data.numpy()
            diff = self.network_params[i] - p_np
            # print(diff)
            scalar_diff = np.sum(diff ** 2)
            total_diff += scalar_diff
        return total_diff

这会有用吗?我跟踪total_diff的时间,并记录它,但似乎总是零。尽管该模型的性能正在提高,但这让我感到非常困惑。

1 个答案:

答案 0 :(得分:1)

原因

这是因为PyTorch处理numpy数组和火炬''' Developer: Roei Edri File name: trcrt.py Date: 24.11.17 Version: 1.1.0 Description: Get an url as an input and prints the traceroute to it. ''' import sys import urllib2 i, o, e = sys.stdin, sys.stdout, sys.stderr from scapy.all import * from scapy.layers.inet import * sys.stdin, sys.stdout, sys.stderr = i, o, e def trcrt(dst): """ Check for the route for the given destination :param dst: Final destination, in a form of a website. :type dst: str """ try: pckt = IP(dst=dst)/ICMP() # Creates the # packet ip = [p for p in pckt.dst] # Gets the ip print "Tracerouting for {0} : {1}".format(dst, ip[0]) for ttl in range(1, 40): pckt = IP(ttl=ttl, dst=dst)/ICMP() timeBefore = time.time() reply = sr1(pckt, verbose=0, timeout=5) timeAfter = time.time() timeForReply = (timeAfter - timeBefore)*1000 if reply is not None: print "{0} : {1} ; Time for reply: {2}".format(ttl, reply.src, timeForReply) if reply.type == 0: print "Tracerout Completed" break else: print "{0} ... Request Time Out".format(ttl) def checkInternet(): """ Checks if there is an internet connection :return: True if there is an internet connection """ try: urllib2.urlopen('http://45.33.21.159', timeout=1) return True except urllib2.URLError as IntError: return False 之间的转换的方式。如果numpy数组和torch Tensor之间的基础数据类型相同,它们将共享内存。更改一个值也会改变另一个的值。我将在这里展示一个具体的例子,

Tensor

然后,如果您更改x 就地并查看x和y中的值,您会发现它们仍然相同。

x = Variable(torch.rand(2, 2))
y = x.data.numpy()
x
Out[39]: 
Variable containing:
 0.8442  0.9968
 0.7366  0.4701
[torch.FloatTensor of size 2x2]
y
Out[40]: 
array([[ 0.84422851,  0.996831  ],
       [ 0.73656738,  0.47010136]], dtype=float32)

因此,在模型更新期间,模型和类x += 2 x Out[42]: Variable containing: 2.8442 2.9968 2.7366 2.4701 [torch.FloatTensor of size 2x2] y Out[43]: array([[ 2.84422851, 2.99683094], [ 2.7365675 , 2.47010136]], dtype=float32) 中的参数将始终相同。这就是你看到零的原因。

如何解决这个问题?

如果numpy数组和火炬Tensor的基础数据类型不兼容,它将强制在火炬Tensor中复制原始数据,这将使numpy数组和火炬Tensor具有单独的内存。

一种简单的方法就是将numpy数组转换为ParameterDiffer类型。而不是

np.float64

您可以使用

network_params.append(p.data.numpy())

重要参考资料

  1. http://pytorch.org/tutorials/beginner/blitz/tensor_tutorial.html#numpy-bridge
  2. https://github.com/pytorch/pytorch/issues/2246