Unity-数字孪生-代理模型:从数据拟合的角度看代理模型

Motivation

最近尝试了一些代理模型的构建方法,其中有些成功了,有些失败了,借此机会,总结一下经验。

为什么要训练代理模型?

这个问题可以转化为:如果不训练代理模型怎么样?
我之前尝试过样本空间的离散点 X = { x 1 , x 2 , . . . , x n } X=\{x_1, x_2,..., x_n\} X={x1,x2,...,xn}对应的结果 Y = { y 1 , y 2 , . . . , y n } Y=\{y_1, y_2, ..., y_n\} Y={y1,y2,...,yn} 对应起来然后放到数据库当中,如果数据当中有足够的 { x : y } \{x:y\} {x:y}配对值之后,如果有新的点,直接取临近的点代替就可以,或者通过该点周围的点进行插值。这样做可以实现比较好的展示效果。链接: 如我上一篇文章所演示的

然而,这样做的其中一个弊端是:不好部署!
什么意思呢?举个例子,如果我的 x x x 才两个维度,每个维度计算100个值,那在二维空间当中便会有10000个值,也就是说,y的值也会有10000个。而像有限元结果,y的值往往会有应力、应变、位移,单元数轻轻松松就会上几十万。即便用了数据库,很快也会炸了。
代理模型便会为上述问题提供一个解决方案。 一般说利用数据来进行学习的代理模型,如SVM, RBF, DNN本质上都是一个拟合过程 Y = F ( X ) Y = F(X) Y=F(X), 代理模型便代表了 F ( ⋅ ) : X → Y F(\cdot):X\rightarrow Y F():XY这个映射关系。

代理模型如何训练?

最简单的视角就是按照数据拟合的角度去看待。为什么要着重强调这一点呢?因为当我对代理模型这个东西觉得神秘的时候,会觉得代理模型这个东西非常高大上,但后来觉得不过如此。

先简单介绍一下我的需求, 我需要做一个demo, 输入是两个力,输出是27000个节点的位移幅值(应力、应变等类似),我想要尝试用已经配对好的数据来训练一个代理模型自动学习其中的映射关系,让我能够摆脱繁重的数据库。

我主要尝试了三种方法:RBF, GAN, MLP, 由于时间的原因,RBF和GAN训练都失败了,而MLP效果还不错。

RBF是是径向基神经网络,也是目前代理模型最为常见的一种。我构建的模型代码如下:

class RBFN(nn.Module):
    """
    以高斯核作为径向基函数
    """
    def __init__(self, centers, n_out=21704):
        """
        :param centers: shape=[center_num,data_dim]
        :param n_out:
        """
        super(RBFN, self).__init__()
        self.n_out = n_out
        self.num_centers = centers.size(0)  # 
        self.dim_centure = centers.size(1)  #

        self.centers = nn.Parameter(centers) #训练中心点
        self.beta = nn.Parameter(torch.ones(1, self.num_centers)* 10, requires_grad=True) #训练方差

        # 对线性层的输入节点数目进行了修改
        self.linear = nn.Linear(self.num_centers, self.n_out, bias=True)
        self.initialize_weights()  # 创建对象时自动执行

    def kernel_fun(self, batches): #高斯核操作
        n_input = batches.size(0)  # number of inputs
        A = self.centers.view(self.num_centers, -1).repeat(n_input, 1, 1)
        B = batches.view(n_input, -1).unsqueeze(1).repeat(1, self.num_centers, 1)
        C = torch.exp(-self.beta.mul((A - B).pow(2).sum(2, keepdim=False)))
        return C

    def forward(self, batches):
        radial_val = self.kernel_fun(batches) 
        class_score = self.linear(radial_val)
        return class_score

    def initialize_weights(self, ):
        """
        网络权重初始化
        :return:
        """
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                m.weight.data.normal_(0, 0.02)
                m.bias.data.zero_()
            elif isinstance(m, nn.ConvTranspose2d):
                m.weight.data.normal_(0, 0.02)
                m.bias.data.zero_()
            elif isinstance(m, nn.Linear):
                m.weight.data.normal_(0, 0.02)
                m.bias.data.zero_()

    def print_network(self):
        num_params = 0
        for param in self.parameters():
            num_params += param.numel()
        print(self)
        print('Total number of parameters: %d' % num_params)

因为我想即时看到训练效果,相比于将其导入到Unity去看云图的渲染效果,我直接用时域和频域展示原数据和代理模型生成的结果。
原数据将其展开成时域和频域的结果如下:
在这里插入图片描述
1、RBF最后训练的输出倒是和这个差不多,但是它好像只学习到了这一种情况:
在这里插入图片描述
导入到Unity当中的效果和实测数据差不多,但是没有明显的颜色的变化。
在这里插入图片描述

2、GAN太难训练了,GAN的Genenrator还没学习到这种情况就收敛了。
在这里插入图片描述
导入到Unity当中的效果是这样的:
在这里插入图片描述

3、用MLP则是出乎意料得训练成功了。模型特别简单:

# 神经网络结构
class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.layer1 = nn.Linear(2, 128)
        self.layer2 = nn.Linear(128, 21704)

    def forward(self, x):
        x = torch.relu(self.layer1(x))
        x = self.layer2(x)
        return x

在这里插入图片描述
导入到Unity当中的效果和用实测数据差不多,效果很好。视频演示放B站了

  • 25
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
### 回答1: #提问者没有完整的问题,无法给出全面的回答,请完善问题# 如果您要问的是如何使用Python和Unity进行Socket通信,那么我可以为您提供一些信息。Socket通信是指通过网络连接在不同的计算机上进行数据传输的过程。Python和Unity可以通过Socket协议实现实时的数据传输和通信。 对于Python和Unity之间的Socket通信,Python负责服务器端,Unity负责客户端。Python服务器将数据发送到Unity客户端,Unity客户端接收并解析数据。最常用的Socket协议是TCP(Transmission Control Protocol)协议,它提供了单一的连接,并将数据包使用特殊的数据结构进行编码和解码。 在开始使用Python和Unity进行Socket通信之前,需要安装Python的Socket模块和Unity的网络功能模块。然后,需要编写Python服务器和Unity客户端的代码,实现数据的发送和接收。 Python Socket模块是Python用于网络编程的核心模块。它提供了内置的套接字对象,可用于创建和操作Socket。在此基础上,可以编写一个Python服务器端程序,并绑定到IP地址和端口上。 Unity客户端使用C#,其自带的网络功能模块可以用于发送和接收数据。在Unity,需要创建网络Socket连接,并进行连接、发送和接收操作。 总的来说,Python和Unity之间的Socket通信需要使用TCP协议,并需要编写Python服务器和Unity客户端的代码,才能实现数据的实时传输和通信。在实际工程,还需要考虑数据格式、安全性等问题。 ### 回答2: #Python-Unity-Socket通信:Unity (C#)的实现 Python-Unity-Socket通信可以让Python代码与Unity (C#)代码实现良好的互动。通过Socket通信,Python和Unity都可以发送和接收网络数据,实现各种场景和功能。 实现Python-Unity Socket通信的步骤如下: 1. 在Python建立Socket服务器(Server),等待Unity连接 2. 在Unity建立Socket客户端(Client),连接到Python Socket服务器 3. Python和Unity互相发送和接收数据 在Python,建立Socket服务器的代码如下: ``` import socket host = '127.0.0.1' port = 8888 s = socket.socket() s.bind((host, port)) s.listen(1) conn, addr = s.accept() print("连接地址:" + str(addr)) while True: data = conn.recv(1024).decode() if not data: break print("接收数据:" + data) conn.sendall(data.encode()) conn.close() ``` 在Unity,建立Socket客户端的代码如下: ``` using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Net.Sockets; using System.Net; using System; public class SocketClient : MonoBehaviour { public string host = "127.0.0.1"; public int port = 8888; private TcpClient client; // Use this for initialization void Start () { try { client = new TcpClient(); client.Connect(host, port); } catch (Exception e) { Debug.Log(e); } string message = "Hello Python"; byte[] data = System.Text.Encoding.UTF8.GetBytes(message); NetworkStream stream = client.GetStream(); stream.Write(data, 0, data.Length); data = new byte[1024]; string responseData = string.Empty; int bytes = stream.Read(data, 0, data.Length); responseData = System.Text.Encoding.UTF8.GetString(data, 0, bytes); Debug.Log("收到服务器消息:" + responseData); stream.Close(); client.Close(); } } ``` 以上代码实现了Unity向Python发送一条消息,并接收Python回传的消息。 Python和Unity之间还可以通过Socket发送和接收其他类型的数据,如音频、视频等。需要注意的是,Python和Unity发送和接收数据的格式需要保持一致,可以使用Json、Protobuf等数据格式来统一。 ### 回答3: # 应该题目描述不太准确,这里按照理解给出回答 python-unity-socket-communication,是指使用Python语言和Unity游戏引擎之间进行网络Socket通信。 具体实现,需要在Unity编写C#代码,通过Socket连接Python服务器,实现网络通信。 在Unity,首先需要使用Socket创建一个客户端连接到Python服务器,并通过该连接向Python服务器发送请求和接收响应。同时,需要编写代码来解析Python服务器返回的数据,以便Unity游戏引擎正确地使用它们。 在Python服务器,需要编写Socket服务器程序,以便监听来自Unity客户端的请求,并对其做出响应。在响应Unity客户端请求时,需要将Python语言数据格式转换为Unity游戏引擎所需的格式。 总之,Python-Unity-Socket通信是一种常用且强大的网络通信方式,可以帮助Unity游戏开发人员高效地与Python服务器进行通信,以实现更为复杂的游戏功能和应用场景。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值