[英]How does Deep Reinforcement Learning remove the need to map or explore every state, action pair for an agent?
我有兴趣使用深度强化学习来教 AI 如何玩游戏,其中 AI 在开始时就知道游戏的模型(所以我会使用基于模型的深度强化学习?)
但是,可以采取的可能状态和动作组合的数量非常大,我无法绘制出每一对。 我听说深度强化学习是这个非常大的状态空间的解决方案,但我不确定如何训练神经网络在任何(未来)状态下采取哪些行动,如果它没有经历过每种可能的状态然而。
任何人都可以就这个问题提供澄清吗?
好,这里有几件事。
首先,在服务器繁忙的情况下,connect设计为在超时之前等待一会儿。 您可以调整超时时间,尽管我不记得确切该怎么做。
其次,您的代码将找到一个服务器,但是您如何知道它在寻找的服务器呢? 可能是其他一些仅在同一端口上监听的应用程序。 除非您仅对任何服务器进行扫描,否则都需要进行一些验证以确保另一端正在与谁交谈。
最后,假设您同时编写客户端和服务器,则更好的解决方案是让客户端发送广播/多播消息,并使服务器(或服务器(如果有多个))侦听并响应该消息。 。 然后,客户端只需等待指定的时间段,以便做出响应以弄清服务器的位置。
我将进行一项研究,以确定winsock是否支持异步I / O。
服务器IP地址是否是如此随机,以至于您每次都需要这样做? 我已经很长时间没有做任何套接字编程了,但是超时了,这样可能不会变得更好。
其他选项:
机器学习中的大多数近似形式也会导致泛化——当出现一个以前没有见过的例子时,能够为目标变量提供优于猜测的估计。
在 RL 之外,使用带有神经网络或其他函数逼近器的训练数据集,实现这种泛化是训练时最常见的目标。 这就是交叉验证和测试数据集的原因,以衡量模型学习概括的程度。
深度强化学习在探索非常大的状态/动作空间时,依赖这种泛化效应来有效学习。
近似器仍然很难在棋盘游戏中很好地概括,在这种情况下,状态的微小差异可能会导致完全不同的结果。 因此,像AlphaZero这样的自学学习系统使用复杂的架构和大量的计算资源在短时间内获得大量的经验(数百万个游戏)。 这仍然远远不能强制所有可能的状态(许多数量级),因此仍然严重依赖泛化。
如果您知道服务器在子网上,为什么不发送带有本地接收端口号作为消息数据的广播消息? 然后,服务器可以简单地侦听此消息并连接回该端口,或者将其自己的配置数据发送回该端口,以便客户端可以直接连接。 这样,您只需要发送一条消息即可,而无需遍历256个IP地址。
过去,在“每个人都有139端口”的开放日里,我都取得了巨大的成功。
我发现使用多个线程(可悲的是,我使用了大约500个线程,但这只是一次射击,只是为了好玩),在尝试连接之前,我对服务器进行了ping操作,使我每秒可以穿越数小时和IP。
我仍然有源代码(C ++),如果您想检查一下,请给我留言。
另外,为什么到底有必要扫描IP? 即使它是动态的,您也应该能够通过其主机名来查找ip。 请参阅gethostbyname()或getaddrinfo()。
我看到您正在使用Windows。 但是,如果您使用的是Linux,则可以通过组合非阻塞套接字来创建具有超时功能的连接函数,然后选择:
int connect_with_timeout(int sock, struct sockaddr *addr, int size_addr, int timeout) {
#if defined(Linux)
int error = 0;
fd_set rset;
fd_set wset;
int n;
// set the socket as nonblocking IO
int flags = fcntl (sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flags | O_NONBLOCK);
errno = 0;
// we connect, but it will return soon
n = connect(sock, addr, size_addr);
if(n < 0) {
if (errno != EINPROGRESS) {
return -1;
}
} else if (n == 0) {
goto done;
}
FD_ZERO(&rset);
FD_ZERO(&wset);
FD_SET(sock, &rset);
FD_SET(sock, &wset);
struct timeval tval;
tval.tv_sec = timeout;
tval.tv_usec = 0;
// We "select()" until connect() returns its result or timeout
n = select(sock + 1, &rset, &wset, 0, timeout ? &tval : 0);
if(n == 0) {
errno = ETIMEDOUT;
return -1;
}
if (FD_ISSET(sock, &rset) || FD_ISSET(sock, &wset)) {
socklen_t len = sizeof(error);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
return -1;
}
} else {
return -1;
}
done:
// We change the socket options back to blocking IO
if (fcntl(sock, F_SETFL, flags) == -1) {
return -1;
}
return 0;
#else
return connect(sock, addr, size_addr);
#endif
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.