Python 如何加速dict的构造,该dict的值是按条件填充的?

Python 如何加速dict的构造,该dict的值是按条件填充的?,python,dictionary,Python,Dictionary,我需要建立一个新的字典,它的值是有条件地填充的。我的问题是;我需要搜索数百万个项目才能做到这一点。下面是我尝试用少量的信息来做这件事,但在实践中,我需要用数百倍于其大小的东西来做同样的事情,这将需要几个小时 import torch, copy import numpy as np # initialize model class mlp1(torch.nn.Module): def __init__(self, num_features, num_hidden, num_classe

我需要建立一个新的字典,它的值是有条件地填充的。我的问题是;我需要搜索数百万个项目才能做到这一点。下面是我尝试用少量的信息来做这件事,但在实践中,我需要用数百倍于其大小的东西来做同样的事情,这将需要几个小时

import torch, copy
import numpy as np

# initialize model
class mlp1(torch.nn.Module):
    def __init__(self, num_features, num_hidden, num_classes):
        super(mlp1, self).__init__()
        self.num_classes = num_classes
        self.input_layer = torch.nn.Linear(num_features, num_hidden)
        self.out_layer = torch.nn.Linear(num_hidden, num_classes)

    def forward(self, x):
        x = self.input_layer(x)
        x = torch.sigmoid(x)
        logits = self.out_layer(x)
        probas = torch.softmax(logits, dim=1)
        return logits, probas

# instantiate model
model = mlp1(num_features=28*28, num_hidden=100, num_classes=10)

# initial params
initial_dict = copy.deepcopy(model.state_dict())

# trained params
trained_dict = copy.deepcopy(model.state_dict())  # pretend its different

# masks
mask = {
         name: torch.tensor(np.random.choice([False, True],
                                              size=torch.numel(weight),
                                              p=[0.5, 0.5]).reshape(weight.shape))
                for name, weight in initial_dict.items()
                }

# create a new model state
#### how to improve this ####
result = {}
# for each key
for key in initial_dict.keys():
    # if key is not in the new dict
    if key not in result:
        # add it
        result[key] = []
    # get current shape to reshape later
    current_shape = initial_dict[key].shape
    # for each value in each dict
    for v1, v2, v3 in zip(initial_dict[key], trained_dict[key], mask[key]):
        # if multidimensional
        if len(v1.shape) >= 1:
            # loop again
            for vv1, vv2, vv3 in zip(v1, v2, v3):
                # if mask condition is met
                if vv3.item() == True:
                    # append trained dict values
                    result[key].append(vv2.item())
                    # other wise
                else:
                    # append initial dict values
                    result[key].append(vv1.item())
        # else if not multidimensional
        elif len(v1.shape) <= 1:
            # if mask condition is met
            if v3.item() == True:
                # if do the same as bove
                result[key].append(vv2.item())
            else:
                result[key].append(vv1.item())
    # turn key to tensor
    result[key] = torch.as_tensor(result[key])
    # reshape
    result[key] = result[key].reshape(current_shape)
#### how to improve this ####

编辑2:
解决方法是使用矢量化操作,我想这应该是已知的。

一些提高性能的技巧:

结果字典具有基于初始字典键的键。当您解包初始字典键(它们是唯一的)时,保证不会看到同一个键两次。因此,如果钥匙不在检查中,您可以保存自己的


将键和值一起解包,而不是使用键然后查找值

for key, value in initial_dict.items():
  print(key, value)

使用字典理解(用于下面的优化C代码),而不是制作一个空字典并添加到其中

e、 g

initial={a:10,“b:11}
double={k:v*2表示k,v在initial.items()中为v}
#{a:20,“b:22}

为了使用字典理解,您需要将多行逻辑封装到一个函数中并调用该函数。这对提高代码的可读性和可重用性都有好处

def过程(初始值、训练值、掩码值):
形状=初始值。形状
输出=[]
#你的逻辑。。。
output.append(1)
output.append(2)
返回输出
结果_dict={k:k初始_dict.items()中k,v的过程(v,经过训练的_dict[v],掩码[v])
你对多维数组使用嵌套循环听起来也是一个可以优化的领域。你能用一次迭代来代替嵌套吗?你能用字典或列表理解来至少提高当前逻辑的速度吗


风格评论:

对于Python样式,当涉及到布尔值时,使用
is True
而不是
==True

你的v2和vv2等变量是模糊的。它们需要合适的名称。这样你就不必评论这是经过训练的或初始的


另外,您的if和elif语句只有两个分支,其中一个分支保证会被命中,因此可以将其设置为just if和else。

非常感谢这篇超详细的文章。我认为我没有击中目标,因为我所做的工作产生了基本相同的运行时间,从快速的%timeit判断。我添加了我对fn所做的工作如果你能继续帮助我更好地改进这个过程,请在上面编辑。代码看起来好多了。每一秒的注释都没有什么意义,实际上使代码更难阅读。我很失望你没有看到速度的提高。也许你可以使用np数组而不是输出列表?Numpy和Pandas一直很麻烦y在C级进行了优化,也有很多方法可以使相同的任务在C级完成,并获得不同的速度。我还建议使用库或IDE工具进行Python评测。这将告诉您逻辑的哪个部分计算时间最长,然后您可以对其进行优化。您的输入数据有多大?也许几个小时是合理的您可以将其作为一项长期运行的任务。您可以通过在云中的增强硬件上运行它,甚至将数据拆分为多个部分,并在多台机器上并行处理来加速它。您甚至可以在本地尝试。使用Python库的多核处理在单个脚本中很难实现。但是,也许你可以在4个终端窗口中开始编写脚本,使用4个内核(你需要研究如何确保每次使用不同的内核),然后通过并行处理,速度将提高4倍。当然,你必须在它们之间拆分输入数据,并重新组合4个输出数据。
for key, value in initial_dict.items():
  print(key, value)