diff --git a/categories/docker/index.html b/categories/docker/index.html index 6a310d5..e6f006a 100644 --- a/categories/docker/index.html +++ b/categories/docker/index.html @@ -8,7 +8,8 @@ Cancel文章标签分类 -

 Docker

2023

diff --git a/categories/docker/index.xml b/categories/docker/index.xml index 4cd5c3f..5f6df00 100644 --- a/categories/docker/index.xml +++ b/categories/docker/index.xml @@ -1 +1 @@ -Docker - Category - yizhigopher的博客http://plutolove233.github.io/categories/docker/Docker - Category - yizhigopher的博客Hugo -- gohugo.iozh-CNyizhigopher@163.com (yizhigopher)yizhigopher@163.com (yizhigopher)Thu, 30 Nov 2023 14:37:10 +0800容器运行方式http://plutolove233.github.io/docker-run/Thu, 30 Nov 2023 14:37:10 +0800yizhigopherhttp://plutolove233.github.io/docker-run/如何运行容器 在之前的几篇文章中,我们学习了如何使用docker的指令以及如何进行容器打包,接下来我们就需要了解,该如何运行容器。 最简单的方式docker常用命令以及镜像打包http://plutolove233.github.io/docker-cmd/Tue, 14 Nov 2023 21:11:15 +0800yizhigopherhttp://plutolove233.github.io/docker-cmd/基本操作 在上节,我们已经安装好docker,但是就如同写代码一样,我们安装好了相关环境,但是并没有代码能够让我们运行,我们又不会写代码(自己docker介绍以及安装步骤说明http://plutolove233.github.io/docker-introduce/Tue, 14 Nov 2023 19:45:12 +0800yizhigopherhttp://plutolove233.github.io/docker-introduce/什么是docker docker可以说是一门技术、一种软件,它能够帮助我们将程序进行打包,从而方便后续的项目部署以及维护。 为什么要用docke \ No newline at end of file +Docker - Category - yizhigopher的博客http://plutolove233.github.io/categories/docker/Docker - Category - yizhigopher的博客Hugo -- gohugo.iozh-CNyizhigopher@163.com (yizhigopher)yizhigopher@163.com (yizhigopher)Tue, 29 Oct 2024 19:44:43 +0800如何实现多个个容器之间的通讯http://plutolove233.github.io/docker-connection/Tue, 29 Oct 2024 19:44:43 +0800yizhigopherhttp://plutolove233.github.io/docker-connection/为了进行多个容器之间通讯的实验,首先我们需要创建两个服务,分别打包成不同的镜像,并通过docker-compose进行容器编排。本次实验的项容器运行方式http://plutolove233.github.io/docker-run/Thu, 30 Nov 2023 14:37:10 +0800yizhigopherhttp://plutolove233.github.io/docker-run/如何运行容器 在之前的几篇文章中,我们学习了如何使用docker的指令以及如何进行容器打包,接下来我们就需要了解,该如何运行容器。 最简单的方式docker常用命令以及镜像打包http://plutolove233.github.io/docker-cmd/Tue, 14 Nov 2023 21:11:15 +0800yizhigopherhttp://plutolove233.github.io/docker-cmd/基本操作 在上节,我们已经安装好docker,但是就如同写代码一样,我们安装好了相关环境,但是并没有代码能够让我们运行,我们又不会写代码(自己docker介绍以及安装步骤说明http://plutolove233.github.io/docker-introduce/Tue, 14 Nov 2023 19:45:12 +0800yizhigopherhttp://plutolove233.github.io/docker-introduce/什么是docker docker可以说是一门技术、一种软件,它能够帮助我们将程序进行打包,从而方便后续的项目部署以及维护。 为什么要用docke \ No newline at end of file diff --git a/categories/index.html b/categories/index.html index 290ad90..e9d540e 100644 --- a/categories/index.html +++ b/categories/index.html @@ -8,5 +8,5 @@
Cancel文章标签分类 -
+
\ No newline at end of file diff --git a/categories/index.xml b/categories/index.xml index cbac4e0..44a83e2 100644 --- a/categories/index.xml +++ b/categories/index.xml @@ -1 +1 @@ -Categories - Category - yizhigopher的博客http://plutolove233.github.io/categories/Categories - Category - yizhigopher的博客Hugo -- gohugo.iozh-CNyizhigopher@163.com (yizhigopher)yizhigopher@163.com (yizhigopher)Tue, 08 Oct 2024 15:47:15 +0800golang之路http://plutolove233.github.io/categories/golang%E4%B9%8B%E8%B7%AF/Tue, 08 Oct 2024 15:47:15 +0800yizhigopherhttp://plutolove233.github.io/categories/golang%E4%B9%8B%E8%B7%AF/vscode插件配置设置http://plutolove233.github.io/categories/vscode%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE%E8%AE%BE%E7%BD%AE/Mon, 22 Jan 2024 14:48:37 +0800yizhigopherhttp://plutolove233.github.io/categories/vscode%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE%E8%AE%BE%E7%BD%AE/cudahttp://plutolove233.github.io/categories/cuda/Thu, 14 Dec 2023 15:11:01 +0800yizhigopherhttp://plutolove233.github.io/categories/cuda/golang小技巧http://plutolove233.github.io/categories/golang%E5%B0%8F%E6%8A%80%E5%B7%A7/Mon, 04 Dec 2023 19:13:11 +0800yizhigopherhttp://plutolove233.github.io/categories/golang%E5%B0%8F%E6%8A%80%E5%B7%A7/Dockerhttp://plutolove233.github.io/categories/docker/Thu, 30 Nov 2023 14:37:10 +0800yizhigopherhttp://plutolove233.github.io/categories/docker/Hugohttp://plutolove233.github.io/categories/hugo/Sun, 12 Nov 2023 15:39:14 +0800yizhigopherhttp://plutolove233.github.io/categories/hugo/机器学习之路http://plutolove233.github.io/categories/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B9%8B%E8%B7%AF/Fri, 10 Nov 2023 20:48:46 +0800yizhigopherhttp://plutolove233.github.io/categories/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B9%8B%E8%B7%AF/ \ No newline at end of file +Categories - Category - yizhigopher的博客http://plutolove233.github.io/categories/Categories - Category - yizhigopher的博客Hugo -- gohugo.iozh-CNyizhigopher@163.com (yizhigopher)yizhigopher@163.com (yizhigopher)Tue, 29 Oct 2024 19:44:43 +0800Dockerhttp://plutolove233.github.io/categories/docker/Tue, 29 Oct 2024 19:44:43 +0800yizhigopherhttp://plutolove233.github.io/categories/docker/golang之路http://plutolove233.github.io/categories/golang%E4%B9%8B%E8%B7%AF/Tue, 08 Oct 2024 15:47:15 +0800yizhigopherhttp://plutolove233.github.io/categories/golang%E4%B9%8B%E8%B7%AF/vscode插件配置设置http://plutolove233.github.io/categories/vscode%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE%E8%AE%BE%E7%BD%AE/Mon, 22 Jan 2024 14:48:37 +0800yizhigopherhttp://plutolove233.github.io/categories/vscode%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE%E8%AE%BE%E7%BD%AE/cudahttp://plutolove233.github.io/categories/cuda/Thu, 14 Dec 2023 15:11:01 +0800yizhigopherhttp://plutolove233.github.io/categories/cuda/golang小技巧http://plutolove233.github.io/categories/golang%E5%B0%8F%E6%8A%80%E5%B7%A7/Mon, 04 Dec 2023 19:13:11 +0800yizhigopherhttp://plutolove233.github.io/categories/golang%E5%B0%8F%E6%8A%80%E5%B7%A7/Hugohttp://plutolove233.github.io/categories/hugo/Sun, 12 Nov 2023 15:39:14 +0800yizhigopherhttp://plutolove233.github.io/categories/hugo/机器学习之路http://plutolove233.github.io/categories/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B9%8B%E8%B7%AF/Fri, 10 Nov 2023 20:48:46 +0800yizhigopherhttp://plutolove233.github.io/categories/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B9%8B%E8%B7%AF/ \ No newline at end of file diff --git a/cliffwalking/index.html b/cliffwalking/index.html index ee4960d..812565e 100644 --- a/cliffwalking/index.html +++ b/cliffwalking/index.html @@ -1,5 +1,5 @@ DQN算法示例:CliffWalking问题 - yizhigopher的博客 -
\ No newline at end of file diff --git a/docker-connection/index.html b/docker-connection/index.html new file mode 100644 index 0000000..1933eab --- /dev/null +++ b/docker-connection/index.html @@ -0,0 +1,456 @@ +如何实现多个个容器之间的通讯 - yizhigopher的博客 +

Contents

如何实现多个个容器之间的通讯

Contents +

为了进行多个容器之间通讯的实验,首先我们需要创建两个服务,分别打包成不同的镜像,并通过docker-compose进行容器编排。本次实验的项目目录如下:

 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+
├── client
+│   ├── dockerfile
+│   ├── index.html
+│   └── nginx.conf
+├── docker-compose.yml
+├── microservice1
+│   ├── dockerfile
+│   ├── main
+│   └── main.go
+└── microservice2
+    ├── dockerfile
+    ├── main
+    └── main.go
+

microservice后端服务定义

我们定义了两个后端服务,其代码如下:

 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+
// microservice1/main.go
+package main
+
+import (
+	"encoding/json"
+	"net/http"
+)
+
+type Resp struct {
+	Code    int
+	Message string
+}
+
+func main() {
+	http.HandleFunc("/say_hello", func(w http.ResponseWriter, r *http.Request) {
+		w.Header().Set("Access-Control-Allow-Origin", "*")             //允许访问所有域
+		w.Header().Add("Access-Control-Allow-Headers", "Content-Type") //header的类型
+		w.Header().Set("content-type", "application/json")
+		var data Resp
+		if r.Method != "GET" {
+			data = Resp{
+				Code:    4000,
+				Message: "Only Allow GET Method!",
+			}
+		} else {
+			data = Resp{
+				Code:    2000,
+				Message: "Hello Microservice1",
+			}
+		}
+		resp, _ := json.Marshal(data)
+		w.Write(resp)
+	})
+	http.ListenAndServe(":8080", nil)
+}
+

编译上述代码:

1
+
GOOS=linux GOARCH=amd64 go build main.go
+

另一个后端服务代码如下:

 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+
// microservice2/main.go
+package main
+
+import (
+	"encoding/json"
+	"net/http"
+)
+
+func main() {
+	http.HandleFunc("/who_am_i", func(w http.ResponseWriter, r *http.Request) {
+		w.Header().Set("Access-Control-Allow-Origin", "*")             //允许访问所有域
+		w.Header().Add("Access-Control-Allow-Headers", "Content-Type") //header的类型
+		w.Header().Set("content-type", "application/json") 
+		data := struct{
+			Code int
+			Message string
+		}{
+			Code: 2000,
+			Message: "I am yizhigopher!",
+		}
+		resp, _ := json.Marshal(data)
+		w.Write(resp)
+	})
+	http.ListenAndServe(":8080", nil)
+}
+

使用上述命令编译代码。 +并编写容器build脚本,每个后端服务的dockerfile一样:

1
+2
+3
+4
+5
+
FROM golang:1.23-alpine
+WORKDIR /app
+COPY ./main /app/microservice
+EXPOSE 8080
+ENTRYPOINT ["/app/microservice"]
+

前端界面定义

为了直观体现出不同容器之间通讯作用,我们编写了如下前端代码:

 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+
<!-- client/index.html -->
+<!DOCTYPE html>
+<html lang="CH-ZN">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    
+    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
+</head>
+
+<body>
+    <button onclick="say_hello()" style="width:100px; height:20px">call say hello</button>
+    <br/>
+    <button onclick="whoami()" style="width:100px; height:20px">call who am i</button>
+</body>
+
+</html>
+<script>
+    function say_hello() {
+        $.ajax({
+            url: "http://localhost/api/v1/say_hello",
+            type: "GET",
+            dataType: "json",
+            async: true,
+            success: function(res) {
+                console.log(res)
+            },
+            error: function(param) {
+                console.log("fail, error=", param)
+            }
+        })
+    }
+    function whoami() {
+        $.ajax({
+            url: "http://localhost/api/v2/who_am_i",
+            type: "GET",
+            dataType: "json",
+            async: true,
+            success: function(res) {
+                console.log(res)
+            },
+            error: function(param) {
+                console.log("fail, error=", param)
+            }
+        })
+    }
+</script>
+

需要注意的是,其中每个接口请求的url为:http://localhost/api/v1/say_hellohttp://localhost/api/v2/who_am_i。并编写nginx.conf配置代理:

 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+
user  nginx;
+worker_processes  auto;
+
+error_log  /var/log/nginx/error.log warn;
+pid        /var/run/nginx.pid;
+
+events {
+    worker_connections  1024;
+}
+
+http {
+    include       /etc/nginx/mime.types;
+    default_type  application/octet-stream;
+
+    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+                      '$status $body_bytes_sent "$http_referer" '
+                      '"$http_user_agent" "$http_x_forwarded_for"';
+
+    access_log  /var/log/nginx/access.log  main;
+
+    sendfile        on;
+    keepalive_timeout  65;
+
+    # Server block for handling requests
+    server {
+        listen 80;
+        server_name localhost;
+
+        # 处理静态文件的请求(如果有)
+        location / {
+            root /fontend;
+            index index.html;
+        }
+
+        location ^~/api/v1/ {
+            proxy_pass http://router_one:8080/;
+            proxy_set_header Host $host;
+            proxy_set_header X-Real-IP $remote_addr;
+            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        }
+
+        location ^~/api/v2/ {
+            proxy_pass http://router_two:8080/;
+            proxy_set_header Host $host;
+            proxy_set_header X-Real-IP $remote_addr;
+            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        }
+    }
+}
+

我们注意到,代理的转发路径分别是http://router_one:8080/http://router_two:8080/,其中不是IP地址,而是容器名

容器编排以及通信测试

编写docker-compose.yml编排内容,配置如下:

 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+
version: '3'
+
+services:
+  font_end:
+    image: fontend:v1
+    build: ./client
+    container_name: font_end
+    ports:
+      - 80:80
+    volumes:
+      - ./client/index.html:/fontend/index.html
+      - ./client/nginx.conf:/etc/nginx/nginx.conf
+    networks:
+      - deploy
+
+  microservice1: # 服务名,用于docker-compose中不同服务之间的通讯
+    image: microservice1:v1 # 镜像名
+    build: ./microservice1 # build镜像的地址
+    container_name: router_one # 容器名,用于不同容器之间的通讯
+    ports:
+      - 8080:8080
+    volumes:
+      - ./microservice1/main:/app/microservice
+    networks:
+      - deploy
+
+  microservice2:
+    image: microservice2:v1
+    build: ./microservice2
+    container_name: router_two
+    ports:
+      - 8081:8080
+    volumes:
+      - ./microservice2/main:/app/microservice
+    networks:
+      - deploy
+    
+networks: # 设定网段
+  deploy:  
+    driver: bridge # 配置为桥接模式
+

运行docker-compose up,编排结果如下: +./result-docker.png +启动并访问http://localhost,结果如下: +./result1.png +./result2.png +观察上图,发现前后端对接成功,nginx成功向不同容器转发请求,实现了不同容器之间的通讯。

+
\ No newline at end of file diff --git a/docker-connection/index.md b/docker-connection/index.md new file mode 100644 index 0000000..2929f0f --- /dev/null +++ b/docker-connection/index.md @@ -0,0 +1,256 @@ +# 如何实现多个个容器之间的通讯 + + +为了进行多个容器之间通讯的实验,首先我们需要创建两个服务,分别打包成不同的镜像,并通过docker-compose进行容器编排。本次实验的项目目录如下: +``` +├── client +│ ├── dockerfile +│ ├── index.html +│ └── nginx.conf +├── docker-compose.yml +├── microservice1 +│ ├── dockerfile +│ ├── main +│ └── main.go +└── microservice2 + ├── dockerfile + ├── main + └── main.go +``` +# microservice后端服务定义 +我们定义了两个后端服务,其代码如下: +```go +// microservice1/main.go +package main + +import ( + "encoding/json" + "net/http" +) + +type Resp struct { + Code int + Message string +} + +func main() { + http.HandleFunc("/say_hello", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") //允许访问所有域 + w.Header().Add("Access-Control-Allow-Headers", "Content-Type") //header的类型 + w.Header().Set("content-type", "application/json") + var data Resp + if r.Method != "GET" { + data = Resp{ + Code: 4000, + Message: "Only Allow GET Method!", + } + } else { + data = Resp{ + Code: 2000, + Message: "Hello Microservice1", + } + } + resp, _ := json.Marshal(data) + w.Write(resp) + }) + http.ListenAndServe(":8080", nil) +} +``` +编译上述代码: +```shell +GOOS=linux GOARCH=amd64 go build main.go +``` +另一个后端服务代码如下: +```go +// microservice2/main.go +package main + +import ( + "encoding/json" + "net/http" +) + +func main() { + http.HandleFunc("/who_am_i", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") //允许访问所有域 + w.Header().Add("Access-Control-Allow-Headers", "Content-Type") //header的类型 + w.Header().Set("content-type", "application/json") + data := struct{ + Code int + Message string + }{ + Code: 2000, + Message: "I am yizhigopher!", + } + resp, _ := json.Marshal(data) + w.Write(resp) + }) + http.ListenAndServe(":8080", nil) +} +``` +使用上述命令编译代码。 +并编写容器build脚本,每个后端服务的dockerfile一样: +``` +FROM golang:1.23-alpine +WORKDIR /app +COPY ./main /app/microservice +EXPOSE 8080 +ENTRYPOINT ["/app/microservice"] +``` +# 前端界面定义 +为了直观体现出不同容器之间通讯作用,我们编写了如下前端代码: +```html + + + + + + + + + + + + + + +
+ + + + + +``` +需要注意的是,其中每个接口请求的url为:**http://localhost/api/v1/say_hello**和**http://localhost/api/v2/who_am_i**。并编写nginx.conf配置代理: +```nginx +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + keepalive_timeout 65; + + # Server block for handling requests + server { + listen 80; + server_name localhost; + + # 处理静态文件的请求(如果有) + location / { + root /fontend; + index index.html; + } + + location ^~/api/v1/ { + proxy_pass http://router_one:8080/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location ^~/api/v2/ { + proxy_pass http://router_two:8080/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + } +} + +``` +我们注意到,代理的转发路径分别是**http://router_one:8080/**和**http://router_two:8080/**,其中不是IP地址,而是**容器名**。 +# 容器编排以及通信测试 +编写`docker-compose.yml`编排内容,配置如下: +```yml +version: '3' + +services: + font_end: + image: fontend:v1 + build: ./client + container_name: font_end + ports: + - 80:80 + volumes: + - ./client/index.html:/fontend/index.html + - ./client/nginx.conf:/etc/nginx/nginx.conf + networks: + - deploy + + microservice1: # 服务名,用于docker-compose中不同服务之间的通讯 + image: microservice1:v1 # 镜像名 + build: ./microservice1 # build镜像的地址 + container_name: router_one # 容器名,用于不同容器之间的通讯 + ports: + - 8080:8080 + volumes: + - ./microservice1/main:/app/microservice + networks: + - deploy + + microservice2: + image: microservice2:v1 + build: ./microservice2 + container_name: router_two + ports: + - 8081:8080 + volumes: + - ./microservice2/main:/app/microservice + networks: + - deploy + +networks: # 设定网段 + deploy: + driver: bridge # 配置为桥接模式 +``` +运行`docker-compose up`,编排结果如下: +![](./result-docker.png) +启动并访问`http://localhost`,结果如下: +![](./result1.png) +![](./result2.png) +观察上图,发现前后端对接成功,nginx成功向不同容器转发请求,实现了不同容器之间的通讯。 diff --git a/docker-connection/result-docker.png b/docker-connection/result-docker.png new file mode 100644 index 0000000..6fa1aa7 Binary files /dev/null and b/docker-connection/result-docker.png differ diff --git a/docker-connection/result1.png b/docker-connection/result1.png new file mode 100644 index 0000000..e541b1a Binary files /dev/null and b/docker-connection/result1.png differ diff --git a/docker-connection/result2.png b/docker-connection/result2.png new file mode 100644 index 0000000..87baef6 Binary files /dev/null and b/docker-connection/result2.png differ diff --git a/go-install/index.html b/go-install/index.html index 378bd87..6eb80f4 100644 --- a/go-install/index.html +++ b/go-install/index.html @@ -1,5 +1,5 @@ Go语言环境安装 - yizhigopher的博客 -
\ No newline at end of file diff --git a/index.html b/index.html index 967847b..fc83dfa 100644 --- a/index.html +++ b/index.html @@ -18,7 +18,7 @@  published on  included in Hugo
为什么要用Action来实现自动化部署hugo项目 不采用自动化部署,每次更新项目时,都需要在本地编译,然后上传整个public目录,比较麻烦
Read More
 github自动化部署

强化学习数学知识总结

 published on  
基本概念: 对于强化学习,我们一般会分成智能体(agent),环境(通过智能体的状态和动作反馈信息)两大部分,我们现在介绍一些名词,从而有利于
Read More

pytorch实现线性拟合

 published on  
安装pytorch 我们以英伟达显卡为例,我们需要知道自己电脑对应cuda版本信息: 在控制台输入nvidia-smi我们可以看到对应cuda版
Read More

DQN算法示例:CliffWalking问题

 published on  
问题描述 给定一个4×12的网格环境,如下图所示,其中黄色区域表示悬崖,我们不能经过,蓝色是我们的目标区域,我们希望能求出每个状态如何利用最少
Read More

Go语言环境安装

 published on  
在本节中,我们将首先简单介绍下如何安装Go语言环境,以开启Go语言学习之路!我们将简单介绍在Windows环境,Linux环境以及Mac环境
Read More

Todotree插件设置

 published on  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
Read More
published on  机器学习之路
问题描述 给定一个4×12的网格环境,如下图所示,其中黄色区域表示悬崖,我们不能经过,蓝色是我们的目标区域,我们希望能求出每个状态如何利用最少
Read More
 pytorchDQNRL

如何实现多个个容器之间的通讯

 published on  
为了进行多个容器之间通讯的实验,首先我们需要创建两个服务,分别打包成不同的镜像,并通过docker-compose进行容器编排。本次实验的项
Read More

Go语言环境安装

 published on  
在本节中,我们将首先简单介绍下如何安装Go语言环境,以开启Go语言学习之路!我们将简单介绍在Windows环境,Linux环境以及Mac环境
Read More
\ No newline at end of file diff --git a/index.json b/index.json index 5d1d478..24de5db 100644 --- a/index.json +++ b/index.json @@ -1 +1 @@ -[{"categories":["Hugo"],"content":"为什么要用Action来实现自动化部署hugo项目 不采用自动化部署,每次更新项目时,都需要在本地编译,然后上传整个public目录,比较麻烦 不采用自动化部署,没办法管理博客内容以及维护 ","date":"2023-11-12","objectID":"/workflow/:0:1","tags":["github","自动化部署"],"title":"如何利用GitHub的Action实现hugo项目自动化部署","uri":"/workflow/"},{"categories":["Hugo"],"content":"怎样实现 在github上创建 {{ username }}.github.io仓库,在main分支的基础上,新建source分支用于存放hugo的markdown文件,而main分支用于存放编译好后的文件 前期准备: 在本地,使用ssh工具创建公私钥 ssh-keygen -t rsa -N '' -f ./deploy-key -q 在本地我们会得到deploy-key和deploy-key.pub两个文件 现在需要将ssh密钥信息设置到仓库中: 添加deploy-key信息 deploy key的title随便填写即可,我们将生成的deploy-key.pub(即公钥)的内容填到key中 设置action的密钥: 新建一个actions secret 其中Name的内容填为ACTIONS_DEPLOY_KEY,Secret的内容填为我们生成的deploy-key(即私钥)的内容。 在source分支中添加.github/workflows/main.yml文件,用于定义Github Actions,其中main.yaml文件内容为 name: auto-update-page # 定义action名称 on: push: branches: - source # 当source分支出现push行为时,执行这个action jobs: deploy: runs-on: ubuntu-22.04 # 定义环境以及之后的行为 steps: - uses: actions/checkout@v4 with: submodules: true # Fetch Hugo themes (true OR recursive) fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: hugo-version: \"0.120.3\" extended: true - name: Build run: hugo --minify - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }} publish_dir: ./public external_repository: plutolove233/plutolove233.github.io publish_branch: main # 将编译好的public里面的内容部署到对应仓库的分支上 设置完之后,我们查看仓库的Actions,我们能够看到: 看到如上内容,就意味着我们自动化部署的工作流完成了,我们可以尝试修改部分markdown文件,上传之后我们可以看到我们的博客内容也会发生改变 ","date":"2023-11-12","objectID":"/workflow/:0:2","tags":["github","自动化部署"],"title":"如何利用GitHub的Action实现hugo项目自动化部署","uri":"/workflow/"},{"categories":["机器学习之路"],"content":"基本概念: 对于强化学习,我们一般会分成智能体(agent),环境(通过智能体的状态和动作反馈信息)两大部分,我们现在介绍一些名词,从而有利于之后学习的理解。在这一部分,我们会结合一个3×3的网格寻路来形象化介绍下述概念。 我们最初位置是在(1,1),我们希望能够在最短的时间内到达蓝色网格位置。 State:agent相对于environment的状态。例如以s1表示网格(1,1),s9表示网格(3,3)。所有的状态会构成S(State Set)。 Action:每个状态可能采取的行动。例如向上(a1)、下(a3)、左(a4)、右(a2)走,这所有的动作会构成A(Action Set)。 state transition:agent从s1→s4的过程。 state transition probability:用条件概率的形式,表示转移的情况。例如p(s4|s1, a3)=0.5表示从状态s1执行动作a3(向下)到达状态s4的可能性是0.5(因为还可以向右到达s2的可能)。 Reward:一个数字,用于表示一个state transition行为所产生的激励。 forbidden area:进入但是会产生损失的区域(Reward\u003c0)。例如图示中的黄色区域。 Policy:让agent知道在某个状态该如何行动,也是用条件概率的形式来表示,例如π(a1|s1)=0,π(a2|s1)=0.5。同时我们应该还满足下述条件: $$ \\sum_{a\\in A}\\pi(a|s_j) = 1 $$ Trajectory:是整个状态行为链,例如s1(a2)→s2(a3)→s5(a3)→s8(a2)→s9(a4)→s8… Return:表示整个Trajectory上Reward之和 Discounted Rate:由上可知,一个Trajectory可能是无穷无尽的,所以我们需要定义γ来种折扣Reward,从而使整个过程的Return不会太大。 Discounted Return:表示整个Trajectory的折扣回报总和,具体表示为: $$ Discounted\\ Return=\\sum_{i=1}^\\infin \\gamma^{i-1}r_i $$ 我们可以知道,这个结果最终会收敛到一个值。并且γ越小,那么Discounted Return会与最早的reward相关(更近视),γ越大也就越远视 Episode:一个有限步的Trajectory,并且最终状态时terminal state(目标状态,即图中蓝色方块)。 ","date":"2023-11-10","objectID":"/concept/:0:1","tags":["RL","math"],"title":"强化学习数学知识总结","uri":"/concept/"},{"categories":["机器学习之路"],"content":"马尔可夫过程 随机过程 随机过程研究的对象是,随时间改变的随机现象。例如本例子中,时刻1在状态s1,时刻2可能就会在s2获s4。这一过程是随机的,我们通常用 $$ P(s_{t+1}|a_{t+1},s_{t}, a_{t}, s_{t-1}…a_1, s_0) $$ 来表示下一个时刻,状态的可能性 马尔可夫性质 当前状态只与上一个状态有关时,我们称这个过程具有马尔可夫性质,即 $$ P(s_{t+1}|a_{t+1},s_{t}, a_{t}, s_{t-1}…a_1, s_0)=P(s_{t+1}|a_{t+1}, s_t) $$ 在本例子中,每个时刻到达某个网格的状态可能完全取决于上一时刻所在状态和动作,所以我们这个网格寻路的例子是满足马尔可夫性质的。 几个新的概率 $$ P(s’|s, a)表示s\\stackrel{a}{\\longrightarrow}s’即从s执行动作a到达s’的概率\\\\ P(r |s, a)表示s\\stackrel{a}{\\longrightarrow}s’这一过程获得reward=r的概率\\\\ $$ 新的概念 State Value $$ v_{\\pi}(s)=\\mathbb{E}(G_t|S=s)\\\\ $$ 回报矩阵G:表示当前时刻所有状态所获得的discounted return $$ G_t=R_{t+1}+\\gamma G_{t+1} $$ 贝尔曼公式 我们将上述式子进行展开以及归纳,可得贝尔曼公式: $$ \\forall s\\in S,v_{\\pi}(s)=\\mathbb{E}(G_t|S_t=s)=\\mathbb{E}(R_{t+1}|S_t=s)+\\gamma\\mathbb{E}(G_{t+1}|S_t=s)\\\\ =\\sum_{a\\in A}\\pi(a|s)\\sum_rp(r|s,a)r + \\gamma\\sum_{s’}\\mathbb{E}(G_{t+1}|S_{t+1}=s’,S_t=s)P(s’|s)\\\\ =\\sum_{a\\in A}\\pi(a|s)\\sum_rp(r|s,a)r +\\gamma\\sum_{s’}v_{\\pi}(s’)\\sum_{a\\in A}P(s’|s, a)\\pi(a|s) $$ 我们将这个公式化成矩阵的形式 $$ \\mathbf{v_{\\pi}}=\\mathbf{r_{\\pi}}+\\gamma\\mathbf{P_{\\pi}}\\mathbf{v_{\\pi}} $$ 其中: $$ r_{\\pi}(s)=\\sum_{a\\in A}\\pi(a|s)\\sum_rp(r|s,a)r\\\\ P_{\\pi}(s’|s)=\\sum_{a \\in A}p(s’|s,a)\\pi(a|s),即s\\rarr s’的可能性\\\\ \\mathbf{P_{\\pi(i,j)}} = P_{\\pi}(s_j|s_i) $$ 我们该如何求解——求state value 求矩阵的逆 迭代的方式: 先随机设置v0初始值 利用 $$ \\mathbf{v_{k+1}}=\\mathbf{r_{\\pi}}+\\gamma\\mathbf{P_{\\pi}}\\mathbf{v_{k}} $$ 不断进行迭代,当k→∞时,vk→vπ ","date":"2023-11-10","objectID":"/concept/:0:2","tags":["RL","math"],"title":"强化学习数学知识总结","uri":"/concept/"},{"categories":["机器学习之路"],"content":"安装pytorch 我们以英伟达显卡为例,我们需要知道自己电脑对应cuda版本信息: 在控制台输入nvidia-smi我们可以看到对应cuda版本的信息内容: 从上图中,我们可知:当前我们CUDA的版本是11.2,之后我们去pytorch官方网页 查询对应pytorch的版本信息,按照给出的安装命令信息安装即可。 由于pytorch官网并没有cuda11.2的安装方法,所以我选择安装cuda11.1的环境 pip install torch==1.9.1+cu111 torchvision==0.10.1+cu111 torchaudio==0.9.1 -f https://download.pytorch.org/whl/torch_stable.html 我们可以通过一下代码来判断pytorch是否已经正确安装以及识别到显卡驱动 import torch print(torch.cuda.is_available()) print(torch.cuda.current_device()) print(torch.cuda.device_count()) print(torch.cuda.get_device_name(0)) 执行结果如下: ","date":"2023-11-09","objectID":"/linear/:0:1","tags":["pytorch","mechine learning"],"title":"pytorch实现线性拟合","uri":"/linear/"},{"categories":["机器学习之路"],"content":"编写代码 现在我们可以进行代码编写过程了 构造数据集,我们假设拟合的结果是 $$ y=w_1\\times x_1 + w_2\\times x_2 + b\\\\ 即y=\\begin{bmatrix} w_1 \u0026 w_2 \\\\ \\end{bmatrix} \\begin{bmatrix} x_1\\\\ x_2\\\\ \\end{bmatrix}+b $$ 为了能够体现机器学习拟合的有效性,我们在生成数据点时会增加一些噪声,从而体现出数据的混乱 代码实现: def synthetic_data(w, b, num_examples): \"\"\"生成 y = Xw + b + 噪声。\"\"\" X = torch.normal(0, 1, (num_examples, len(w))) # X是均值为0,方差为1的随机数。有num_examples个样本,列就是len(w) y = torch.matmul(X, w) + b # Y是X与w的乘积(matmul == mm,矩阵相乘)加上偏差b y += torch.normal(0, 0.01, y.shape) # 加入一个噪音,均值为0,方差为0.01,形状与y相同 return X, y.reshape((-1, 1)) # 其中,y返回一个列向量。-1表示自动计算,1表示固定,即列向量为1 true_w = torch.tensor([2, -3.4]) true_b = 4.2 features, labels = synthetic_data(true_w, true_b, 1000) 我们可以绘制图像,用于显示我们构造的数据: 然后我们将数据进行封装成Dataset class LinearDataSet(Dataset): def __init__(self, x, y): self.X = torch.FloatTensor(x) self.Y = torch.FloatTensor(y) def __getitem__(self, index): return self.X[index], self.Y[index] def __len__(self): return len(self.X) trainSet = LinearDataSet(features, labels) trainLoader = DataLoader(trainSet, batch_size=10, shuffle=True, pin_memory=True) 我们现在编写网络,以及编写一个训练过程: class LinearNetWork(nn.Module): def __init__(self, n_feature): super(LinearNetWork, self).__init__() self.layers = nn.Sequential( nn.Linear(n_feature, 1) # 定义一个最简单线性全连接层 ) def forward(self, x): y = self.layers(x) return y def Trainer(train_loader: DataLoader, model: LinearNetWork): criterion = nn.MSELoss() # 定义一个均方误差 optimizer = torch.optim.SGD(model.parameters(), lr=0.03) # 定义一个优化器 for i in range(epoch): model.train() for x, y in train_loader: optimizer.zero_grad() # 采用梯度下降,每次训练都需要将梯度信息清零 x, y = x.to(device), y.to(device) pred = model(x) loss = criterion(pred, y) print(\"loss=\", loss.detach().item()) loss.backward() # 梯度回退 optimizer.step() model = LinearNetWork(2).to(device) # 因为我们总共就两个变量,所以我们传入的特征信息为2 Trainer(trainLoader, model) print(model.state_dict()) 这样我们一个最简单的神经网络已经构成,我们执行上述代码查看网络每层的信息: ","date":"2023-11-09","objectID":"/linear/:0:2","tags":["pytorch","mechine learning"],"title":"pytorch实现线性拟合","uri":"/linear/"},{"categories":["机器学习之路"],"content":"总结 总的来说,这次这个任务还是比较简单的,我们构造一个简单的神经网络,完成了最简单的线性拟合的问题,我们可以在这里面一窥机器学习的基本过程。我们需要获取数据、数据处理、构造网络、进行训练、调整参数,然后不断循环往复,从而得到一个加好的结果。 ","date":"2023-11-09","objectID":"/linear/:0:3","tags":["pytorch","mechine learning"],"title":"pytorch实现线性拟合","uri":"/linear/"},{"categories":["机器学习之路"],"content":"问题描述 给定一个4×12的网格环境,如下图所示,其中黄色区域表示悬崖,我们不能经过,蓝色是我们的目标区域,我们希望能求出每个状态如何利用最少的步骤到达目的点。 ","date":"2023-11-10","objectID":"/cliffwalking/:0:1","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["机器学习之路"],"content":"编写工具类代码 # rl_utils.py def one_hot(index, num_size=10): return [1 if i == index else 0 for i in range(num_size)] class ReplayBuffer: def __init__(self, capacity): self.buffer = collections.deque(maxlen=capacity) def add(self, state, action, reward, next_state, done): self.buffer.append((state, action, reward, next_state, done)) def sample(self, batch_size): transitions = random.sample(self.buffer, batch_size) state, action, reward, next_state, done = zip(*transitions) return np.array(state), action, reward, np.array(next_state), done def size(self): return len(self.buffer) def train_off_policy_agent(env, agent, num_episodes, replay_buffer, minimal_size, batch_size): return_list = [] for i in range(10): with tqdm(total=int(num_episodes / 10), desc='Iteration %d' % i) as pbar: for i_episode in range(int(num_episodes / 10)): episode_return = 0 state = env.reset()[0] done = False while not done: action = agent.take_action(state) next_state, reward, done, _, _ = env.step(action) replay_buffer.add(state, action, reward, next_state, done) state = next_state episode_return += reward if replay_buffer.size() \u003e minimal_size: b_s, b_a, b_r, b_ns, b_d = replay_buffer.sample(batch_size) transition_dict = {'states': b_s, 'actions': b_a, 'next_states': b_ns, 'rewards': b_r, 'dones': b_d} agent.update(transition_dict) return_list.append(episode_return) if (i_episode + 1) % 10 == 0: pbar.set_postfix({'episode': '%d' % (num_episodes / 10 * i + i_episode + 1), 'return': '%.3f' % np.mean(return_list[-10:])}) pbar.update(1) return return_list ","date":"2023-11-10","objectID":"/cliffwalking/:0:2","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["机器学习之路"],"content":"制定规则 我们规定,每走一步所得的reward是-1,走进悬崖的reward是-100,到达目标地点的reward是100。 我们编写环境代码如下: # grid_world.py class GridWorld: \"\"\" 悬崖问题的环境建立 \"\"\" def __init__(self, row=4, col=12): self.action_num = 4 self.col = col self.row = row self.x = row - 1 self.y = 0 self.statue_dim = self.row*self.col self.action_dim = 4 def step(self, action) -\u003e (list, float, bool, bool, dict): action = int(action) # 假设一个3*3的情景,目的是中间方块,求最短距离 self.x = min(self.row - 1, max(0, self.x + change[action][0])) self.y = min(self.col - 1, max(0, self.y + change[action][1])) next_state = self.x * self.col + self.y reward = -1 done = False if self.x == self.row - 1 and self.y \u003e 0: done = True if self.y != self.col - 1: # enter into hole reward = -100 else: # reach the final reward = 100 nextState = np.array(rl.one_hot(next_state, num_size=self.row * self.col)) return nextState, reward, done, False, {} def reset(self) -\u003e (list, dict): self.x = self.row - 1 self.y = 0 label = self.x * self.col + self.y state = np.array(rl.one_hot(label, num_size=self.row * self.col)) return state, {} 在上述代码中,我们实现了环境的定义,同时,我们注意到,我们返回的状态采用了独热编码,这也就意味着,之后我们构建网络时,输入的维度应该是48。 ","date":"2023-11-10","objectID":"/cliffwalking/:0:3","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["机器学习之路"],"content":"编写神经网络用来拟合QSA target 我们需要知道,这个网络的输入是48,输出应该是action个数。 # grid_world.py class CliffWalkNet(nn.Module): \"\"\" 悬崖问题神经网络构造 \"\"\" def __init__(self, in_dim, hidden_dim, out_dim): super(CliffWalkNet, self).__init__() self.layer = nn.Sequential( nn.Linear(in_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, out_dim) ) def forward(self, x): return self.layer(x) 在里面使用三个全连接层,以及两个隐藏层。 ","date":"2023-11-10","objectID":"/cliffwalking/:0:4","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["机器学习之路"],"content":"编写DQN核心代码 我们每个动作采用ε贪婪策略,以及规定每次操作执行的更新方法 class CliffWalkDQLearning: def __init__(self, in_dim, hidden_dim, action_dim): self.ActionNumber = action_dim self.Q_net = CliffWalkNet(in_dim, hidden_dim, action_dim).to(device) self.Q_target = CliffWalkNet(in_dim, hidden_dim, action_dim).to(device) self.optimizer = torch.optim.Adam(self.Q_net.parameters(), lr=learning_rate) self.criterion = nn.MSELoss() self.count = 0 self.QSA = [[0, 0, 0, 0] for _ in range(in_dim)] def take_action(self, state): if np.random.random() \u003c epsilon: return np.random.randint(self.ActionNumber) state = torch.tensor(state, dtype=torch.float).to(device) return self.Q_net(state).argmax().item() def update(self, transition: dict): # load data from dictionary states_ = torch.tensor(transition.get(\"states\"), dtype=torch.float).to(device) actions_ = torch.tensor(transition.get(\"actions\")).view(-1, 1).to(device) rewards_ = torch.tensor(transition.get(\"rewards\"), dtype=torch.float).view(-1, 1).to(device) next_states_ = torch.tensor(transition.get(\"next_states\"), dtype=torch.float).to(device) dones_ = torch.tensor(transition.get(\"dones\"), dtype=torch.float).view(-1, 1).to(device) q_values = self.Q_net(states_).gather(1, actions_) # 每列收集对应actions_拟合的value值 max_qvalue = self.Q_target(next_states_).max(1)[0].view(-1, 1) q_target = rewards_ + gamma * max_qvalue * (1-dones_) loss = self.criterion(q_values, q_target) self.optimizer.zero_grad() loss.backward() self.optimizer.step() if self.count % update_times == 0: net_state_dict = self.Q_net.state_dict() self.Q_target.load_state_dict(net_state_dict) self.count += 1 ","date":"2023-11-10","objectID":"/cliffwalking/:0:5","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["机器学习之路"],"content":"执行代码,进行模型训练 我们可以直接利用rl_utils里面的(off_policy)工具,进行DQN的训练 env = GridWorld() dim = env.row*env.col agent = CliffWalkDQLearning(in_dim=dim, hidden_dim=int(dim/2), action_dim=4) buffer = rl.ReplayBuffer(1000) random.seed(0) np.random.seed(0) torch.manual_seed(0) return_list = rl.train_off_policy_agent(env, agent, num_episodes, buffer, minimal_size, batch_size) episodes_list = list(range(len(return_list))) plt.plot(episodes_list, return_list) plt.xlabel('Episodes') plt.ylabel('Returns') plt.title('DQN on {}'.format(\"Cliff Walking\")) plt.show() ","date":"2023-11-10","objectID":"/cliffwalking/:0:6","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["机器学习之路"],"content":"模型保存 torch.save({\"CliffWalking\": agent.Q_target.state_dict()}, \"./cliff_walking.pth\") # load model model = CliffWalkNet(in_dim=dim, hidden_dim=int(dim/2), out_dim=4).to(device) state_dict = torch.load(\"./cliff_walking.pth\")[\"CliffWalking\"] model.load_state_dict(state_dict) res = [[0, 0, 0, 0] for _ in range(dim)] for i in range(4): for j in range(12): state = rl.one_hot(i*12+j, dim) input_ = torch.tensor(state, dtype=torch.float).to(device) target = model(input_).cpu().detach().numpy().tolist() res[i*12+j] = target # print(\"state(%d,%d):\" % (i, j)) # print(target) # print() print_agent(res, env, action_graph, list(range(37, 47)), [47]) 我们将训练好的模型保存,之后导入model,这样我们就可以避免重复的模型训练,直接计算每个结点的QSA,寻找每个状态的action最大值,从而得出训练后的策略结果。 由上述结果,我们发现每个状态都已经找到了最优的策略,这个模型的结果还算可以。 ","date":"2023-11-10","objectID":"/cliffwalking/:0:7","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["golang之路"],"content":"在本节中,我们将首先简单介绍下如何安装Go语言环境,以开启Go语言学习之路!我们将简单介绍在Windows环境,Linux环境以及Mac环境下如何安装,尽可能全面的覆盖不同读者所使用的操作系统。 Go语言下载地址 Windows安装 下载windows环境下的zip文件,解压到系统的某个目录中,在我的系统中,我将其解压到本地D盘目录D:\\Program Files\\Go\\go下。 之后在系统的环境变量中将该目录下的bin目录添加到环境变量中,如图所示: 保存后通过打开终端,输入go version即可判断是否添加到环境变量中 之后需申明GOROOT、GOPATH,并将GOPATH目录下的bin目录添加到环境变量中,便于后续调用go install指令安装的命令。 Linux安装 下载图1中的源码包,删除 /usr/local/go 文件夹(如果存在),删除之前安装的 Go,然后将刚刚下载的压缩包解压缩到/usr/local,在 /usr/local/go 中创建一个全新的 GOROOT rm -rf /usr/local/go \u0026\u0026 tar -C /usr/local -xzf go1.23.2.linux-amd64.tar.gz 在PATH环境变量中添加/usr/local/go/bin,在$HOME/.profile或/etc/profile(用于全系统安装)中添加以下一行即可: export GOROOT=/usr/local/go export GOPATH=/data/go export PATH=$GOPATH/bin:$GOROOT/bin:$PATH 之后使用命令source $HOME/.profile激活环境变量配置即可。 Mac安装 安装图1中的.pkg安装文件即可 执行以下命令: cd ~ vim .bash_profile 编辑用户环境变量: export GOPATH=/Users/XXX/go #本地创建的gopath绝对路径 export PATH=$PATH:$GOPATH/bin 激活配置文件source ~/.bash_profile即可。 额外的注意点: 需要注意的是,GOPATH目录下需要创建三个文件夹,分别是src、pkg以及bin,其中bin目录保存go install安装的指令,pkg保存第三方包的源码,src用于在GO111MODULE=off时,在该路径下编写包含第三方包的程序(现在基本不在src下写代码了) 之后我们需要覆写go的几个配置: go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.cn,direct GO111MODULE是Go语言用于管理依赖关系的一种机制,它可以帮助开发者更好地管理项目的依赖包,并且可以确保项目在不同环境下的一致性 GOPROXY表示Go安装第三方包的代理(因为国内众所周知的原因),便于后续直接go get安装第三方包 至此,go的安装已经完成了 ","date":"2024-10-08","objectID":"/go-install/:0:0","tags":["golang","study"],"title":"Go语言环境安装","uri":"/go-install/"},{"categories":["vscode插件配置设置"],"content":" \"todo-tree.regex.regex\": \"((%|#|//|\u003c!--|^\\\\s*\\\\*)\\\\s*($TAGS)|^\\\\s*- \\\\[ \\\\])\", \"todo-tree.regex.regexCaseSensitive\": false, \"todo-tree.general.tags\": [ \"BUG\", \"HACK\", \"FIXME\", \"TODO\", \"todo\", \"bug\", \"tag\", \"done\", \"mark\", \"test\", \"update\", \"[]\", \"[x]\" ], \"todo-tree.highlights.defaultHighlight\": { \"background\": \"#ff9100\", \"foreground\": \"#ffffff\", \"type\": \"text\", \"icon\": \"bug\" }, \"todo-tree.highlights.customHighlight\": { //todo 需要做的功能 \"todo\": { \"icon\": \"alert\", //标签样式 \"background\": \"#c9c552\", //背景色 \"rulerColour\": \"#c9c552\", //外框颜色 \"iconColour\": \"#c9c552\", //标签颜色 }, //bug 必须要修复的BUG \"bug\": { \"background\": \"#ff3737\", \"icon\": \"bug\", \"rulerColour\": \"#eb5c5c\", \"iconColour\": \"#eb5c5c\", }, //tag 标签 \"tag\": { \"background\": \"#38b2f4\", \"icon\": \"tag\", \"rulerColour\": \"#38b2f4\", \"iconColour\": \"#38b2f4\", \"rulerLane\": \"full\" }, //done 已完成 \"done\": { \"background\": \"#328050\", \"icon\": \"check\", \"rulerColour\": \"#5eec95\", \"iconColour\": \"#5eec95\", }, //mark 标记一下 \"mark\": { \"background\": \"#f90\", \"icon\": \"note\", \"rulerColour\": \"#f90\", \"iconColour\": \"#f90\", }, //test 测试代码 \"test\": { \"background\": \"#df7be6\", \"icon\": \"flame\", \"rulerColour\": \"#df7be6\", \"iconColour\": \"#df7be6\", }, //update 优化升级点 \"update\": { \"background\": \"#b14e75\", \"icon\": \"versions\", \"rulerColour\": \"#d65d8e\", \"iconColour\": \"#d65d8e\", }, }, 将上述代码复制到settings.json中即可。 ","date":"2024-01-22","objectID":"/todotree/:0:0","tags":["vscode","extension"],"title":"Todotree插件设置","uri":"/todotree/"},{"categories":null,"content":"归一化流基本内容 什么是标准化流:基于一系列可逆变换,生成样本对应的分布 标准化流的基本原理: 变量替换:$p_x(x)=p_z(f_\\theta(x))|\\det J_{f_\\theta}(x)|$,我们可以理解为通过$z=f_\\theta(x)$,将原先复杂分布,变换成简单易懂的分布形式,其中我们要求$f_\\theta$必须是可逆变换。标准化流的目的就是求得该可逆变换。 在标准化流中,往往会使用多个这样的可逆变换,即$f_\\theta(x)=f_1(x)\\circ f_2(x)…\\circ f_K(x)$ 雅各比行列式求解: $$ \\det J_{f_\\theta}(x)=\\det \\prod_{i=1}^K J_{f_i}(x)=\\prod_{i=1}^K\\det J_{f_i}(x) $$ 利用对数函数,我们可以得到: $$ \\log p_x(x)=\\log p_z(f_{\\theta}(x))+\\sum_{i=1}^K\\log |det J_{f_i}(x)| $$ 我们需要最大化这个概率密度 ","date":"2024-01-06","objectID":"/nf-introduce/:0:1","tags":null,"title":"Normalizing Flow介绍","uri":"/nf-introduce/"},{"categories":null,"content":"论文《A deep generative model for probabilistic energy forecasting in power systems: normalizing flows》的应用: 在该论文中,作者采用标准化流的方式实现了负荷预测功能。作者利用$\\bm x$表示d-1天的负荷数据,用$\\bm c$表示天气信息,希望能够得到符合符合数据分布的分布$p_\\theta(\\bm x|\\bm c)$,从而可以利用该分布得到预测数据$^{\\bm x}$。 在利用归一化流方式对泰迪比赛数据进行负荷预测的尝试中,会进行如下操作: 提取时间数据和天气数据,重新整合原本数据格式,得到归一化流的模型输入格式 其中每一行为某个时刻的负荷数据y和影响负荷的因素(时间因素、天气因素)x。根据日期重新排列数据x,将每个时刻影响负荷的因素横向排列并组合。此时x重新排列为一个$day\\times 960$的矩阵,表现如下: ","date":"2024-01-06","objectID":"/nf-introduce/:0:2","tags":null,"title":"Normalizing Flow介绍","uri":"/nf-introduce/"},{"categories":["cuda"],"content":"创建实例 在阿里云平台上创建实例: 其中我们镜像选择为公共的Ubuntu20.04镜像,当然你也可以选择其他配置好的镜像从而简化之后的步骤。 我们之后会演示如何在一个空白的系统中,安装python、cuda以及pytorch的环境 配置好以上信息之后,我们就能获得一个实例,点击实例操作里的打开即可连接远程主机,之后我们会在这个实力上安装一些新的东西,配置我们需要的环境。 ","date":"2023-12-14","objectID":"/install/:0:1","tags":["cuda","安装教程"],"title":"阿里云PAI平台搭建pytorch-cuda11.4环境","uri":"/install/"},{"categories":["cuda"],"content":"安装基本环境 更新apt源 apt-get update 安装python 十分简单: apt-get install python3 apt-get install python3-venv apt-get install python3-pip 安装完成之后,可以执行 python3 --version 安装cuda所需环境 控制台敲入nvidia-smi获得GPU信息,可以我们所需cuda的版本是11.4 安装libxml2 apt-get install libxml2 配置好时区信息即可 安装gcc环境: apt-get install gcc-7 g++-7 配置gcc版本优先级,不然cuda无法识别到安装好的gcc update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70 --slave /usr/bin/g++ g++ /usr/bin/g++-7 --slave /usr/bin/gcov gcov /usr/bin/gcov-7 update-alternatives --config gcc 敲入gcc --version出现如下信息即可: 安装wget和vim apt-get install wget apt-get install vim 安装cuda 到nvidia官网上找到对应cuda驱动下载信息:如图选择即可 在当前目录下创建一个cuda-installer目录,进入该目录,执行installer中的命令: wget https://developer.download.nvidia.com/compute/cuda/11.4.0/local_installers/cuda_11.4.0_470.42.01_linux.run sh cuda_11.4.0_470.42.01_linux.run 敲入accpet同意协议,在之后的配置中选择如下配置: 安装即可,同时按照给出的提示: 修改/etc/profile文件,设置环境变量。使用vim /etc/profile在文末添加如下信息: export CUDA_HOME=/usr/local/cuda-11.4 export LD_LIBRARY_PATH=/usr/local/cuda-11.4/lib64:$LD_LIBRARY_PATH export PATH=/usr/local/cuda-11.4/bin:$PATH 重起实例,执行nvcc -V出现: 即可。 至此cuda安装完毕 安装Torch 去官网上,找到对应版本执行一下命令即可 pip install torch==1.12.0+cu113 torchvision==0.13.0+cu113 torchaudio==0.12.0 --extra-index-url https://download.pytorch.org/whl/cu113 ","date":"2023-12-14","objectID":"/install/:0:2","tags":["cuda","安装教程"],"title":"阿里云PAI平台搭建pytorch-cuda11.4环境","uri":"/install/"},{"categories":["golang小技巧"],"content":"简介 我们能在go代码中添加一段注释,用来表示一种编译约束 //go:build [tags] 通过这个并且配合go build -tags=\"...\"的方式,就能实现带有约束的编译。 举个例子: 我们编写一下代码:主程序申明如下 //main.go package main var configArr []string func main(){ for _, v := range configArr { print(v, \" \") } } 同时,我们会编写另外两个用于初始化的代码,分别为dev和test //go:build dev package main func init() { configArr = append(configArr, \"dev\") } //go:build test package main func init() { configArr = append(configArr, \"test\") } 我们可以看到,在两个同一包下,我们定义了两个不同的初始化功能,分别为configArr添加相应的内容。 当我们采用不同方式编译代码时,会看到如下情况: 能够看到编译时携带的tag不同,结果也就不同。 我们可以很直观的想到可以通过这种方法,实现不同模式下的编译 ","date":"2023-12-04","objectID":"/tips-1/:0:1","tags":["golang","tips"],"title":"go语言小技巧--编译约束","uri":"/tips-1/"},{"categories":["golang小技巧"],"content":"环境设置 当然我们也可以通过添加//go:build linux的方式对本段代码进行编译环境的限制。 例如我们对上述代码的go:build注释进行修改,可以看到如下效果: //go:build linux package main func init() { configArr = append(configArr, \"dev\") } //go:build windows package main func init() { configArr = append(configArr, \"test\") } 这时,我们直接进行代码编译,能够看到如下效果: 可以看到,我们只将test部分的代码编译,而dev的代码并没有编译 ","date":"2023-12-04","objectID":"/tips-1/:0:2","tags":["golang","tips"],"title":"go语言小技巧--编译约束","uri":"/tips-1/"},{"categories":["golang小技巧"],"content":"格式 举个例子:// go:build linux \u0026\u0026 amd64 \u0026\u0026 !cgo || darwin,通过这个我们就能发现,可以通过逻辑运算符来表明编译约束。 ","date":"2023-12-04","objectID":"/tips-1/:0:3","tags":["golang","tips"],"title":"go语言小技巧--编译约束","uri":"/tips-1/"},{"categories":["Docker"],"content":"如何运行容器 在之前的几篇文章中,我们学习了如何使用docker的指令以及如何进行容器打包,接下来我们就需要了解,该如何运行容器。 最简单的方式: 使用docker run或docker start指令来运行镜像或容器 但是这种方式在面对需要进行容器的端口映射、镜像卷以及容器间的网络通信时,会比较麻烦,不易操作。 同时,如果某个容器额外需要依赖另一个容器的存在,即容器之间存在关联的关系时,容器的启动顺序就比较重要了。举个简单的例子,我们手头有个web服务容器,这个容器需要依赖另一个MySQL容器的存在,这时,我们就需要先在web服务容器运行前,先运行MySQL容器。也许你会认为这种情况下,容器的先后顺序并不会对你造成困扰,但是如果容器数量多了怎么办,容器运行的相关参数特别多怎么办。亦或者经过了较长时间,你忘记了这个依赖关系怎么办? 这时候我们就需要有一个工具来管理容器运行的相关参数以及依赖关系。 ","date":"2023-11-30","objectID":"/docker-run/:0:1","tags":null,"title":"容器运行方式","uri":"/docker-run/"},{"categories":["Docker"],"content":"docker-compose工具 如何安装 Windows环境下,因为docker-desktop自带docker-compose,所以不需要关注如何安装 Linux环境下,访问docker-compose的下载地址Releases · docker/compose (github.com) ,选择适合系统的以及相应架构的可运行程序。运行sudo chmod +x docker-compose赋予其可运行能力,让后将该可执行文件放入环境变量的目录下即可 编写docker-compose.yml文件 当我们已经将容器打包完成之后,我们可以编写docker-compose.yml文件,从而能够运行容器。 我们举个简单的例子:在这个例子中,我们只需要申明其镜像卷的挂载即可 verison: '3' services: cliffwalking: image: demo:v1 container_name: reinforce_learning volumes: - /home/yizhigopher/cliffwalk/ouput:/cliffwalking/output - /home/yizhigopher/cliffwalk/model:/cliffwalking/model 我们只需要在当前docker-compose.yml的目录下,运行docker-compose up就能够运行一个名为reinforce_learning的容器,并且将容器内部的output和model文件夹的内容和容器外部的对应的文件夹相关联. 当然,docker-compose能够识别的关键字不止以上这些内容,我们可以通过访问Docker Compose overview | Docker Docs 以及菜鸟教程Docker Compose | 菜鸟教程 (runoob.com) 获得相关的更多信息.以上只是一个简单的示例,希望能够通过这些能够让读者一窥docker-compose容器编排的高效以及优越性 ","date":"2023-11-30","objectID":"/docker-run/:0:2","tags":null,"title":"容器运行方式","uri":"/docker-run/"},{"categories":["Docker"],"content":"结语 至此,docker的相关知识基本分享完毕,事实上,仅仅通过短短的三个博文是不能说明白docker的,也不可能就仅仅读这些内容就能掌握docker.这三篇博文,仅仅能够让大家对docker有个基本的了解,以及基本操作的熟悉.想要熟练掌握docker,还需要经过自己大量的实践练习和操作才能真正熟悉. ","date":"2023-11-30","objectID":"/docker-run/:0:3","tags":null,"title":"容器运行方式","uri":"/docker-run/"},{"categories":["Docker"],"content":"基本操作 在上节,我们已经安装好docker,但是就如同写代码一样,我们安装好了相关环境,但是并没有代码能够让我们运行,我们又不会写代码(自己构建镜像),那该怎么办。我们可以到github上面寻找一个相关的代码,拉取到本地,然后运行即可。 所以我们现在首先要做的事应该是学会如何拉取镜像到本地。 docker pull 完整的docker pull命令应该是:docker pull ${IMAGE_NAME}:${IMAGE_TAG} 它会从docker的官方镜像仓库中拉取对应的镜像。其中${IMAGE_TAG}部分如果不写,会默认拉取最新的镜像信息。 例如,我们现在运行docker pull hello-world命令,我们看看会发生什么: 我们能够看到,使用了最新的版本(tag),镜像的sha256验证信息,以及从哪里拉取的镜像。所以之后,如果我们需要某种镜像,我们就可以直接pull以下就可以了。 可以通过访问docker hub 上,搜索你想要的基础镜像的信息即可(这一过程需要科学上网),或者使用docker search ${IMAGE_NAME},实在不行利用bing搜索相关信息也是不错的选择 那么我们拉取完了,我们怎么能够确定这个镜像就是在我的电脑上的呢? docker images 我们在控制台输入docker images看看会发生什么: 我们看到,在我们本地存储中,确确实实有一个来自hello-world,TAG是latest的仓库的镜像。 当然你也可以通过docker inspect ${IMAGE_NAME}查看镜像在本地的哪个位置,但是这么做完全没有必要。 我们已经能够确定确确实实有个镜像在本地,那么我们该如何运行这个镜像呢 docker run 完整的docker run指令如下:docker run [OPTIONS] ${IMAGE_NAME} [COMMAND] [ARG...],这样之后会生成一个容器container 其中options常用的是: -v:绑定容器卷,后面紧跟映射关系,具体而言就是将本地文件和容器内的文件相关联。需要注意的是,两处的文件路径用:隔开,前面是本地文件的绝对路径,后面是容器内的绝对路径。例如:docker run -v /home/yizhigopher/result:/project/result xxx:v1 -d:后台运行容器,使用这个option后,我们就不会看到容器运行的结果,而只能看到一个容器ID -p:端口映射。有些时候,我们需要访问容器内的一些服务,例如MySQL容器,我们需要在本地就能连接容器中的MySQL服务,我们可以这么写:docker run -d -p 8080:3306 mysql,这样我们就是将容器内的3306端口映射到本地的8080端口,我们在本地就可以通过访问8080端口获得MySQL服务。 -i:以交互模式运行容器,通常与 -t 同时使用 -t:为容器重新分配一个伪输入终端,通常与 -i 同时使用 上述就是我们一般常用的OPTIONS信息,我们掌握了这些,基本可以应付大部分情况。如果需要其他的操作可以查阅官方文档,或者baidu。 举个例子:在终端执行docker run -it golang:alpine会发生什么: 需要注意的是我们这个命令相当于启动一个容器并进入容器内部。可以观察到,我们终端的位置发生了变化,从root@yizhigopher进入到了容器内部的/go目录下,由此也能看出docker的容器也可看成是一个小型的操作系统,在带有bash工具的容器内部,也可以执行一些简单的终端命令,例如ls、cd等等 既然我们已经学会了如何拉取镜像,如何启动一个容器,那么我们可以学学如何生成一个镜像。 ","date":"2023-11-14","objectID":"/docker-cmd/:0:1","tags":null,"title":"docker常用命令以及镜像打包","uri":"/docker-cmd/"},{"categories":["Docker"],"content":"dockerfile 要实现自己编制一个镜像,我们就得学会dockerfile文件的编写规则。 当然,由于篇幅,这里仅仅提供一些简单的dockerfile文件编写的介绍,学会了这些也就够了,更多详细的说明都可以查看官方文档。 FROM ${IMAGE_NAME} 每个dockerfile都得以FROM作为开始,我们自己构建镜像,需要在一个镜像的基础上加以创作。就如同我们平时编写代码一样,我们不可能从0101二进制串来编写代码,我们会借助编译器等基础环境来高效编写程序。 FROM ${IMAGE_NAME}的意义十分简单,你可以简答地理解为docker pull ${IMAGE_NAME},我们之后的一切操作都是在这个镜像内部执行的 WORKDIR ${FILE_NAME} 这个是自选的,WORKDIR相当于申明一个工作目录,当你的容器运行时,会默认在这个目录下运行。如果这个目录不存在,会自动帮你创建这个目录 COPY ${FILE_PATH} ${CONTAINER_FILE_PATH} 这个步骤会将本地主机下的${FILE_PATH}的内容拷贝到容器内部${CONTAINER_FILE_PATH}目录下。我们需要注意的是,如果你想拷贝一个文件,那么你需要指明这个文件在容器内部的名字,即:COPY ./requirement.txt /project/req.txt。如果你拷贝的是文件夹,那么你同样需要指明这个文件在容器内部的名称。 联系一下Linux系统下的mv指令,会有许多相同之处 需要注意的是,有一个ADD指令和COPY指令十分相似,执行的功能也大致相同,但是ADD会自动将压缩文件进行解压,而MOVE不行 RUN ${COMMAND} 这个命令会在搭建docker镜像时执行,它会执行${COMMAND}命令,通常我们用这条指令来为镜像内容进行修改。例如,我们为python代码进行打包时,会将python源代码COPY到镜像内部,然后会执行RUN pip install -r requirements.txt来安装相关包从而能够运行python代码 CMD ${COMMAND} 这个部分的命令会在容器启动时执行,需要注意的有几点 你可以写多个CMD,但是只有最后一个CMD会执行 CMD的指令会被docker run附带的运行指令覆盖 COMMND的书写格式应写成字符数组的形式,例如ls -a需写成[\"ls\", \"-a\"] ENTRYPOINT ${COMMAND} 这个指令和CMD指令十分相似,但是有一点不同,ENTRYPOINT不会被docker run后的运行指令覆盖,而是会将docker run后面的参数传递给ENTRYPOINT。具体的示例可看这个博文Docker从入门到精通——CMD与ENTRYPOINT区别 。这里就不再赘述。 ok我们大概介绍完了dockerfile需要了解的地方,现在我们来自己编写个dockerfile试试看吧。随便挑一个文件夹,将所需要的文件内容拷贝到这里,然后在这个文件夹下新建一个dockerfile文件(名字就是dockerfile),文件内容如下: 然后在这个文件夹下打开控制台,输入:docker buuild -t cliffwalk:v1 . docker build表示执行构建镜像 -t表示构建的镜像名和镜像tag为cliffwalk:v1 最后的 . 表示使用当前目录下的dockerfile 会出现: 当指令结束后,我们使用docker images就可以看到构建好的镜像信息 由于我们最后使用的是CMD来表示容器运行的指令,所以,我们可以通过docker run的方式来覆盖这条指令来进入容器内部,我们能够看到在/cliffwalking目录下,有我们COPY进去的文件内容: 至此,我们完成了docker的基本命令和镜像打包的学习,最后一章我们会介绍如何高效的启动运行容器镜像 ","date":"2023-11-14","objectID":"/docker-cmd/:0:2","tags":null,"title":"docker常用命令以及镜像打包","uri":"/docker-cmd/"},{"categories":["Docker"],"content":"什么是docker docker可以说是一门技术、一种软件,它能够帮助我们将程序进行打包,从而方便后续的项目部署以及维护。 ","date":"2023-11-14","objectID":"/docker-introduce/:0:1","tags":["docker"],"title":"docker介绍以及安装步骤说明","uri":"/docker-introduce/"},{"categories":["Docker"],"content":"为什么要用docker 场景:做项目开发的同学经常会遇到一个问题,就是这个项目能够在本地上运行,但是换一台电脑却会报各种各样的错误,这个时候不得不面对环境配置这一极其麻烦的问题 所以我们说,docker将过去的程序和系统环境的绑定关系给打破了,只要我们的电脑安装了docker,我就可以通过拉取云端的镜像,无需关注环境的搭建就可以实现跨平台的应用部署。我们不再需要面对繁杂的应用上云出现的环境搭建问题,就可以轻松地使用服务。 ","date":"2023-11-14","objectID":"/docker-introduce/:0:2","tags":["docker"],"title":"docker介绍以及安装步骤说明","uri":"/docker-introduce/"},{"categories":["Docker"],"content":"怎样安装docker 安装docker: Windows系统: 在Windows系统,我们需要确保自己的电脑安装了WSL 以管理员身份打开CMD,并敲入: wsl --install 官方文档:安装 WSL | Microsoft Learn ,可查阅官方文档获得更多的信息。 之后我们前往docker-desktop官方网站Docker Desktop: The #1 Containerization Tool for Developers | Docker 下载最新的docker-desktop即可。 需要注意的是,在使用安装好的docker-desktop之前,我们需要修改几个配置 调整docker虚拟机的位置,不然根据初始设置,会把C盘占满 修改docker的镜像源信息,不然在docker pull拉取镜像时,会特别慢: 将其中的内容替换成下述信息: { \"builder\": { \"gc\": { \"defaultKeepStorage\": \"20GB\", \"enabled\": true } }, \"experimental\": false, \"features\": { \"buildkit\": true }, \"registry-mirrors\": [ \"http://hub-mirror.c.163.com\", \"https://mirror.ccs.tencentyun.com\" ] } 或者直接修改C:\\Users\\{{ USERNAME }}\\.docker\\daemon.json内容为上述信息,重启docker。 判断是否安装成功,在CMD中,敲入: docker version 出现如下信息即可: docker之所以需要在Linux环境下使用,是源于在使用go进行编写docker时,需要借助Linux系统的Namespace和Cgroup隔离机制,所以我们在Windows上运行docker实质上是在Windows上安装了一个虚拟机WSL,在虚拟机的内部执行docker Ubuntu系统: 更新索引:sudo apt-get update 安装:sudo apt install docker.io 修改镜像源:在/etc/docker目录下创建daemon.json,在里面添加: { \"registry-mirrors\": [ \"http://hub-mirror.c.163.com\", \"https://mirror.ccs.tencentyun.com\" ] } 即可 判断是否安装成功,在终端输入:docker --version,出现 即可 CentOS/aliyun服务器: 卸载旧版(如果你之前没有安装过,可跳过这一步) yum remove docker \\ docker-client \\ docker-client-latest \\ docker-common \\ docker-latest \\ docker-latest-logrotate \\ docker-logrotate \\ docker-engine 安装依赖包:yum install -y yum-utils 为了防止是从国外的源下载,所以配置阿里云地址:yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 更新依赖:yum update 安装docker:yum install docker-ce docker-ce-cli containerd.io 配置docker镜像源:同样的在/etc/docker目录下创建daemon.json文件,填入镜像源地址信息即可。 启动docker服务:systemctl start docker 判断是否安装完成:控制台输入docker info,看到镜像源信息更改即为安装成功 当然你可以也可以在其他平台上使用docker info来判断镜像源的地址信息是否成功修改 ","date":"2023-11-14","objectID":"/docker-introduce/:0:3","tags":["docker"],"title":"docker介绍以及安装步骤说明","uri":"/docker-introduce/"},{"categories":["Docker"],"content":"一些最基本的概念 仓库Registry:你可以理解为类似代码仓库的东西,只是这里面存放的不是一段段代码,而是一堆镜像,我们可以通过一些指令来获得或上传镜像信息。 镜像Image:它是一种模板,具有创建docker容器的指令。并且一种镜像是得基于另一种镜像才能构建。我们可以把这个理解为虚拟机安装所需的iso文件,只要我有这个iso文件,我就可以打造多个一样的虚拟机环境。当然我们还可以在这个iso的基础上附带一些东西,构成一个新的iso。例如centos分为minimal(最基础的)以及desktop(带有桌面UI的),desktop就是基于minimal,同时又添加了新的东西形成的新的iso文件。 容器Container:它是一种运行实例,每个容器之间是相互隔离互不影响的。同样的,我们举个例子,当你拥有一个iso文件时,你不把它放在VMware中产生一个虚拟机实例,那么这个iso文件也就毫无用处。而你使用同一个iso文件创建的不同虚拟机之间也是不会有任何影响,你不会发现,在A虚拟机中创建了一个文件,B虚拟机中也可以找到。 如果上述的例子还是不能让你理解这三者之间的关系和实际的作用,我们可以拿日常开发做一个例子。仓库Registry就是github.com;镜像就是github.com中的pytorch项目代码,我们可以利用pytorch本身的东西创建一个新的例如predict的项目代码,当然我们也可以上传到github;容器就相当于我们执行这段代码的进程,每个进程之间不会相互影响(不考虑使用共享内存,管道等方式实现进程间的控制)。 ","date":"2023-11-14","objectID":"/docker-introduce/:0:4","tags":["docker"],"title":"docker介绍以及安装步骤说明","uri":"/docker-introduce/"},{"categories":["Docker"],"content":"总结 在这一章中,我们大概介绍了docker的一些基本信息和安装方式,在下一章我们会在ubuntu系统上介绍docker的基本操作。 ","date":"2023-11-14","objectID":"/docker-introduce/:0:5","tags":["docker"],"title":"docker介绍以及安装步骤说明","uri":"/docker-introduce/"},{"categories":null,"content":"个人介绍 出生于2002年6月,喜欢go语言,LOL的蒟蒻。 目前在华北电力大学就读软件工程本科学业。 目前正在学习强化学习,希望能够通过编写个人博客来增加我学习的动力,以及记录我学习的过程。 博客会更新什么 本科以及之后研究生学习的过程和结果 go语言相关的内容,会包括最新特性,以及我觉得有用的东西 docker应用示例,我希望通过几个简短的章节能够让你了解docker如何部署一个项目 或许还会有一些每周心得体会什么的? 我也希望能够有人在阅读我的博客之后,发送email(yizhigopher@163.com)和我交流,希望能够在各位大佬变得更强,无限进步。 ","date":"2023-11-08","objectID":"/about/:0:0","tags":null,"title":"About","uri":"/about/"},{"categories":null,"content":"这是我的第一份博客,用于测试 package main import \"fmt\" func main(){ fmt.Println(\"Hello World\") } $$ \\sum_{i=0}^{100}i = 5050 $$ ","date":"2023-11-08","objectID":"/first_post/:0:0","tags":["hugo"],"title":"First_post","uri":"/first_post/"}] \ No newline at end of file +[{"categories":["Hugo"],"content":"为什么要用Action来实现自动化部署hugo项目 不采用自动化部署,每次更新项目时,都需要在本地编译,然后上传整个public目录,比较麻烦 不采用自动化部署,没办法管理博客内容以及维护 ","date":"2023-11-12","objectID":"/workflow/:0:1","tags":["github","自动化部署"],"title":"如何利用GitHub的Action实现hugo项目自动化部署","uri":"/workflow/"},{"categories":["Hugo"],"content":"怎样实现 在github上创建 {{ username }}.github.io仓库,在main分支的基础上,新建source分支用于存放hugo的markdown文件,而main分支用于存放编译好后的文件 前期准备: 在本地,使用ssh工具创建公私钥 ssh-keygen -t rsa -N '' -f ./deploy-key -q 在本地我们会得到deploy-key和deploy-key.pub两个文件 现在需要将ssh密钥信息设置到仓库中: 添加deploy-key信息 deploy key的title随便填写即可,我们将生成的deploy-key.pub(即公钥)的内容填到key中 设置action的密钥: 新建一个actions secret 其中Name的内容填为ACTIONS_DEPLOY_KEY,Secret的内容填为我们生成的deploy-key(即私钥)的内容。 在source分支中添加.github/workflows/main.yml文件,用于定义Github Actions,其中main.yaml文件内容为 name: auto-update-page # 定义action名称 on: push: branches: - source # 当source分支出现push行为时,执行这个action jobs: deploy: runs-on: ubuntu-22.04 # 定义环境以及之后的行为 steps: - uses: actions/checkout@v4 with: submodules: true # Fetch Hugo themes (true OR recursive) fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: hugo-version: \"0.120.3\" extended: true - name: Build run: hugo --minify - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }} publish_dir: ./public external_repository: plutolove233/plutolove233.github.io publish_branch: main # 将编译好的public里面的内容部署到对应仓库的分支上 设置完之后,我们查看仓库的Actions,我们能够看到: 看到如上内容,就意味着我们自动化部署的工作流完成了,我们可以尝试修改部分markdown文件,上传之后我们可以看到我们的博客内容也会发生改变 ","date":"2023-11-12","objectID":"/workflow/:0:2","tags":["github","自动化部署"],"title":"如何利用GitHub的Action实现hugo项目自动化部署","uri":"/workflow/"},{"categories":["机器学习之路"],"content":"基本概念: 对于强化学习,我们一般会分成智能体(agent),环境(通过智能体的状态和动作反馈信息)两大部分,我们现在介绍一些名词,从而有利于之后学习的理解。在这一部分,我们会结合一个3×3的网格寻路来形象化介绍下述概念。 我们最初位置是在(1,1),我们希望能够在最短的时间内到达蓝色网格位置。 State:agent相对于environment的状态。例如以s1表示网格(1,1),s9表示网格(3,3)。所有的状态会构成S(State Set)。 Action:每个状态可能采取的行动。例如向上(a1)、下(a3)、左(a4)、右(a2)走,这所有的动作会构成A(Action Set)。 state transition:agent从s1→s4的过程。 state transition probability:用条件概率的形式,表示转移的情况。例如p(s4|s1, a3)=0.5表示从状态s1执行动作a3(向下)到达状态s4的可能性是0.5(因为还可以向右到达s2的可能)。 Reward:一个数字,用于表示一个state transition行为所产生的激励。 forbidden area:进入但是会产生损失的区域(Reward\u003c0)。例如图示中的黄色区域。 Policy:让agent知道在某个状态该如何行动,也是用条件概率的形式来表示,例如π(a1|s1)=0,π(a2|s1)=0.5。同时我们应该还满足下述条件: $$ \\sum_{a\\in A}\\pi(a|s_j) = 1 $$ Trajectory:是整个状态行为链,例如s1(a2)→s2(a3)→s5(a3)→s8(a2)→s9(a4)→s8… Return:表示整个Trajectory上Reward之和 Discounted Rate:由上可知,一个Trajectory可能是无穷无尽的,所以我们需要定义γ来种折扣Reward,从而使整个过程的Return不会太大。 Discounted Return:表示整个Trajectory的折扣回报总和,具体表示为: $$ Discounted\\ Return=\\sum_{i=1}^\\infin \\gamma^{i-1}r_i $$ 我们可以知道,这个结果最终会收敛到一个值。并且γ越小,那么Discounted Return会与最早的reward相关(更近视),γ越大也就越远视 Episode:一个有限步的Trajectory,并且最终状态时terminal state(目标状态,即图中蓝色方块)。 ","date":"2023-11-10","objectID":"/concept/:0:1","tags":["RL","math"],"title":"强化学习数学知识总结","uri":"/concept/"},{"categories":["机器学习之路"],"content":"马尔可夫过程 随机过程 随机过程研究的对象是,随时间改变的随机现象。例如本例子中,时刻1在状态s1,时刻2可能就会在s2获s4。这一过程是随机的,我们通常用 $$ P(s_{t+1}|a_{t+1},s_{t}, a_{t}, s_{t-1}…a_1, s_0) $$ 来表示下一个时刻,状态的可能性 马尔可夫性质 当前状态只与上一个状态有关时,我们称这个过程具有马尔可夫性质,即 $$ P(s_{t+1}|a_{t+1},s_{t}, a_{t}, s_{t-1}…a_1, s_0)=P(s_{t+1}|a_{t+1}, s_t) $$ 在本例子中,每个时刻到达某个网格的状态可能完全取决于上一时刻所在状态和动作,所以我们这个网格寻路的例子是满足马尔可夫性质的。 几个新的概率 $$ P(s’|s, a)表示s\\stackrel{a}{\\longrightarrow}s’即从s执行动作a到达s’的概率\\\\ P(r |s, a)表示s\\stackrel{a}{\\longrightarrow}s’这一过程获得reward=r的概率\\\\ $$ 新的概念 State Value $$ v_{\\pi}(s)=\\mathbb{E}(G_t|S=s)\\\\ $$ 回报矩阵G:表示当前时刻所有状态所获得的discounted return $$ G_t=R_{t+1}+\\gamma G_{t+1} $$ 贝尔曼公式 我们将上述式子进行展开以及归纳,可得贝尔曼公式: $$ \\forall s\\in S,v_{\\pi}(s)=\\mathbb{E}(G_t|S_t=s)=\\mathbb{E}(R_{t+1}|S_t=s)+\\gamma\\mathbb{E}(G_{t+1}|S_t=s)\\\\ =\\sum_{a\\in A}\\pi(a|s)\\sum_rp(r|s,a)r + \\gamma\\sum_{s’}\\mathbb{E}(G_{t+1}|S_{t+1}=s’,S_t=s)P(s’|s)\\\\ =\\sum_{a\\in A}\\pi(a|s)\\sum_rp(r|s,a)r +\\gamma\\sum_{s’}v_{\\pi}(s’)\\sum_{a\\in A}P(s’|s, a)\\pi(a|s) $$ 我们将这个公式化成矩阵的形式 $$ \\mathbf{v_{\\pi}}=\\mathbf{r_{\\pi}}+\\gamma\\mathbf{P_{\\pi}}\\mathbf{v_{\\pi}} $$ 其中: $$ r_{\\pi}(s)=\\sum_{a\\in A}\\pi(a|s)\\sum_rp(r|s,a)r\\\\ P_{\\pi}(s’|s)=\\sum_{a \\in A}p(s’|s,a)\\pi(a|s),即s\\rarr s’的可能性\\\\ \\mathbf{P_{\\pi(i,j)}} = P_{\\pi}(s_j|s_i) $$ 我们该如何求解——求state value 求矩阵的逆 迭代的方式: 先随机设置v0初始值 利用 $$ \\mathbf{v_{k+1}}=\\mathbf{r_{\\pi}}+\\gamma\\mathbf{P_{\\pi}}\\mathbf{v_{k}} $$ 不断进行迭代,当k→∞时,vk→vπ ","date":"2023-11-10","objectID":"/concept/:0:2","tags":["RL","math"],"title":"强化学习数学知识总结","uri":"/concept/"},{"categories":["机器学习之路"],"content":"安装pytorch 我们以英伟达显卡为例,我们需要知道自己电脑对应cuda版本信息: 在控制台输入nvidia-smi我们可以看到对应cuda版本的信息内容: 从上图中,我们可知:当前我们CUDA的版本是11.2,之后我们去pytorch官方网页 查询对应pytorch的版本信息,按照给出的安装命令信息安装即可。 由于pytorch官网并没有cuda11.2的安装方法,所以我选择安装cuda11.1的环境 pip install torch==1.9.1+cu111 torchvision==0.10.1+cu111 torchaudio==0.9.1 -f https://download.pytorch.org/whl/torch_stable.html 我们可以通过一下代码来判断pytorch是否已经正确安装以及识别到显卡驱动 import torch print(torch.cuda.is_available()) print(torch.cuda.current_device()) print(torch.cuda.device_count()) print(torch.cuda.get_device_name(0)) 执行结果如下: ","date":"2023-11-09","objectID":"/linear/:0:1","tags":["pytorch","mechine learning"],"title":"pytorch实现线性拟合","uri":"/linear/"},{"categories":["机器学习之路"],"content":"编写代码 现在我们可以进行代码编写过程了 构造数据集,我们假设拟合的结果是 $$ y=w_1\\times x_1 + w_2\\times x_2 + b\\\\ 即y=\\begin{bmatrix} w_1 \u0026 w_2 \\\\ \\end{bmatrix} \\begin{bmatrix} x_1\\\\ x_2\\\\ \\end{bmatrix}+b $$ 为了能够体现机器学习拟合的有效性,我们在生成数据点时会增加一些噪声,从而体现出数据的混乱 代码实现: def synthetic_data(w, b, num_examples): \"\"\"生成 y = Xw + b + 噪声。\"\"\" X = torch.normal(0, 1, (num_examples, len(w))) # X是均值为0,方差为1的随机数。有num_examples个样本,列就是len(w) y = torch.matmul(X, w) + b # Y是X与w的乘积(matmul == mm,矩阵相乘)加上偏差b y += torch.normal(0, 0.01, y.shape) # 加入一个噪音,均值为0,方差为0.01,形状与y相同 return X, y.reshape((-1, 1)) # 其中,y返回一个列向量。-1表示自动计算,1表示固定,即列向量为1 true_w = torch.tensor([2, -3.4]) true_b = 4.2 features, labels = synthetic_data(true_w, true_b, 1000) 我们可以绘制图像,用于显示我们构造的数据: 然后我们将数据进行封装成Dataset class LinearDataSet(Dataset): def __init__(self, x, y): self.X = torch.FloatTensor(x) self.Y = torch.FloatTensor(y) def __getitem__(self, index): return self.X[index], self.Y[index] def __len__(self): return len(self.X) trainSet = LinearDataSet(features, labels) trainLoader = DataLoader(trainSet, batch_size=10, shuffle=True, pin_memory=True) 我们现在编写网络,以及编写一个训练过程: class LinearNetWork(nn.Module): def __init__(self, n_feature): super(LinearNetWork, self).__init__() self.layers = nn.Sequential( nn.Linear(n_feature, 1) # 定义一个最简单线性全连接层 ) def forward(self, x): y = self.layers(x) return y def Trainer(train_loader: DataLoader, model: LinearNetWork): criterion = nn.MSELoss() # 定义一个均方误差 optimizer = torch.optim.SGD(model.parameters(), lr=0.03) # 定义一个优化器 for i in range(epoch): model.train() for x, y in train_loader: optimizer.zero_grad() # 采用梯度下降,每次训练都需要将梯度信息清零 x, y = x.to(device), y.to(device) pred = model(x) loss = criterion(pred, y) print(\"loss=\", loss.detach().item()) loss.backward() # 梯度回退 optimizer.step() model = LinearNetWork(2).to(device) # 因为我们总共就两个变量,所以我们传入的特征信息为2 Trainer(trainLoader, model) print(model.state_dict()) 这样我们一个最简单的神经网络已经构成,我们执行上述代码查看网络每层的信息: ","date":"2023-11-09","objectID":"/linear/:0:2","tags":["pytorch","mechine learning"],"title":"pytorch实现线性拟合","uri":"/linear/"},{"categories":["机器学习之路"],"content":"总结 总的来说,这次这个任务还是比较简单的,我们构造一个简单的神经网络,完成了最简单的线性拟合的问题,我们可以在这里面一窥机器学习的基本过程。我们需要获取数据、数据处理、构造网络、进行训练、调整参数,然后不断循环往复,从而得到一个加好的结果。 ","date":"2023-11-09","objectID":"/linear/:0:3","tags":["pytorch","mechine learning"],"title":"pytorch实现线性拟合","uri":"/linear/"},{"categories":["机器学习之路"],"content":"问题描述 给定一个4×12的网格环境,如下图所示,其中黄色区域表示悬崖,我们不能经过,蓝色是我们的目标区域,我们希望能求出每个状态如何利用最少的步骤到达目的点。 ","date":"2023-11-10","objectID":"/cliffwalking/:0:1","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["机器学习之路"],"content":"编写工具类代码 # rl_utils.py def one_hot(index, num_size=10): return [1 if i == index else 0 for i in range(num_size)] class ReplayBuffer: def __init__(self, capacity): self.buffer = collections.deque(maxlen=capacity) def add(self, state, action, reward, next_state, done): self.buffer.append((state, action, reward, next_state, done)) def sample(self, batch_size): transitions = random.sample(self.buffer, batch_size) state, action, reward, next_state, done = zip(*transitions) return np.array(state), action, reward, np.array(next_state), done def size(self): return len(self.buffer) def train_off_policy_agent(env, agent, num_episodes, replay_buffer, minimal_size, batch_size): return_list = [] for i in range(10): with tqdm(total=int(num_episodes / 10), desc='Iteration %d' % i) as pbar: for i_episode in range(int(num_episodes / 10)): episode_return = 0 state = env.reset()[0] done = False while not done: action = agent.take_action(state) next_state, reward, done, _, _ = env.step(action) replay_buffer.add(state, action, reward, next_state, done) state = next_state episode_return += reward if replay_buffer.size() \u003e minimal_size: b_s, b_a, b_r, b_ns, b_d = replay_buffer.sample(batch_size) transition_dict = {'states': b_s, 'actions': b_a, 'next_states': b_ns, 'rewards': b_r, 'dones': b_d} agent.update(transition_dict) return_list.append(episode_return) if (i_episode + 1) % 10 == 0: pbar.set_postfix({'episode': '%d' % (num_episodes / 10 * i + i_episode + 1), 'return': '%.3f' % np.mean(return_list[-10:])}) pbar.update(1) return return_list ","date":"2023-11-10","objectID":"/cliffwalking/:0:2","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["机器学习之路"],"content":"制定规则 我们规定,每走一步所得的reward是-1,走进悬崖的reward是-100,到达目标地点的reward是100。 我们编写环境代码如下: # grid_world.py class GridWorld: \"\"\" 悬崖问题的环境建立 \"\"\" def __init__(self, row=4, col=12): self.action_num = 4 self.col = col self.row = row self.x = row - 1 self.y = 0 self.statue_dim = self.row*self.col self.action_dim = 4 def step(self, action) -\u003e (list, float, bool, bool, dict): action = int(action) # 假设一个3*3的情景,目的是中间方块,求最短距离 self.x = min(self.row - 1, max(0, self.x + change[action][0])) self.y = min(self.col - 1, max(0, self.y + change[action][1])) next_state = self.x * self.col + self.y reward = -1 done = False if self.x == self.row - 1 and self.y \u003e 0: done = True if self.y != self.col - 1: # enter into hole reward = -100 else: # reach the final reward = 100 nextState = np.array(rl.one_hot(next_state, num_size=self.row * self.col)) return nextState, reward, done, False, {} def reset(self) -\u003e (list, dict): self.x = self.row - 1 self.y = 0 label = self.x * self.col + self.y state = np.array(rl.one_hot(label, num_size=self.row * self.col)) return state, {} 在上述代码中,我们实现了环境的定义,同时,我们注意到,我们返回的状态采用了独热编码,这也就意味着,之后我们构建网络时,输入的维度应该是48。 ","date":"2023-11-10","objectID":"/cliffwalking/:0:3","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["机器学习之路"],"content":"编写神经网络用来拟合QSA target 我们需要知道,这个网络的输入是48,输出应该是action个数。 # grid_world.py class CliffWalkNet(nn.Module): \"\"\" 悬崖问题神经网络构造 \"\"\" def __init__(self, in_dim, hidden_dim, out_dim): super(CliffWalkNet, self).__init__() self.layer = nn.Sequential( nn.Linear(in_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, out_dim) ) def forward(self, x): return self.layer(x) 在里面使用三个全连接层,以及两个隐藏层。 ","date":"2023-11-10","objectID":"/cliffwalking/:0:4","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["机器学习之路"],"content":"编写DQN核心代码 我们每个动作采用ε贪婪策略,以及规定每次操作执行的更新方法 class CliffWalkDQLearning: def __init__(self, in_dim, hidden_dim, action_dim): self.ActionNumber = action_dim self.Q_net = CliffWalkNet(in_dim, hidden_dim, action_dim).to(device) self.Q_target = CliffWalkNet(in_dim, hidden_dim, action_dim).to(device) self.optimizer = torch.optim.Adam(self.Q_net.parameters(), lr=learning_rate) self.criterion = nn.MSELoss() self.count = 0 self.QSA = [[0, 0, 0, 0] for _ in range(in_dim)] def take_action(self, state): if np.random.random() \u003c epsilon: return np.random.randint(self.ActionNumber) state = torch.tensor(state, dtype=torch.float).to(device) return self.Q_net(state).argmax().item() def update(self, transition: dict): # load data from dictionary states_ = torch.tensor(transition.get(\"states\"), dtype=torch.float).to(device) actions_ = torch.tensor(transition.get(\"actions\")).view(-1, 1).to(device) rewards_ = torch.tensor(transition.get(\"rewards\"), dtype=torch.float).view(-1, 1).to(device) next_states_ = torch.tensor(transition.get(\"next_states\"), dtype=torch.float).to(device) dones_ = torch.tensor(transition.get(\"dones\"), dtype=torch.float).view(-1, 1).to(device) q_values = self.Q_net(states_).gather(1, actions_) # 每列收集对应actions_拟合的value值 max_qvalue = self.Q_target(next_states_).max(1)[0].view(-1, 1) q_target = rewards_ + gamma * max_qvalue * (1-dones_) loss = self.criterion(q_values, q_target) self.optimizer.zero_grad() loss.backward() self.optimizer.step() if self.count % update_times == 0: net_state_dict = self.Q_net.state_dict() self.Q_target.load_state_dict(net_state_dict) self.count += 1 ","date":"2023-11-10","objectID":"/cliffwalking/:0:5","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["机器学习之路"],"content":"执行代码,进行模型训练 我们可以直接利用rl_utils里面的(off_policy)工具,进行DQN的训练 env = GridWorld() dim = env.row*env.col agent = CliffWalkDQLearning(in_dim=dim, hidden_dim=int(dim/2), action_dim=4) buffer = rl.ReplayBuffer(1000) random.seed(0) np.random.seed(0) torch.manual_seed(0) return_list = rl.train_off_policy_agent(env, agent, num_episodes, buffer, minimal_size, batch_size) episodes_list = list(range(len(return_list))) plt.plot(episodes_list, return_list) plt.xlabel('Episodes') plt.ylabel('Returns') plt.title('DQN on {}'.format(\"Cliff Walking\")) plt.show() ","date":"2023-11-10","objectID":"/cliffwalking/:0:6","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["机器学习之路"],"content":"模型保存 torch.save({\"CliffWalking\": agent.Q_target.state_dict()}, \"./cliff_walking.pth\") # load model model = CliffWalkNet(in_dim=dim, hidden_dim=int(dim/2), out_dim=4).to(device) state_dict = torch.load(\"./cliff_walking.pth\")[\"CliffWalking\"] model.load_state_dict(state_dict) res = [[0, 0, 0, 0] for _ in range(dim)] for i in range(4): for j in range(12): state = rl.one_hot(i*12+j, dim) input_ = torch.tensor(state, dtype=torch.float).to(device) target = model(input_).cpu().detach().numpy().tolist() res[i*12+j] = target # print(\"state(%d,%d):\" % (i, j)) # print(target) # print() print_agent(res, env, action_graph, list(range(37, 47)), [47]) 我们将训练好的模型保存,之后导入model,这样我们就可以避免重复的模型训练,直接计算每个结点的QSA,寻找每个状态的action最大值,从而得出训练后的策略结果。 由上述结果,我们发现每个状态都已经找到了最优的策略,这个模型的结果还算可以。 ","date":"2023-11-10","objectID":"/cliffwalking/:0:7","tags":["pytorch","DQN","RL"],"title":"DQN算法示例:CliffWalking问题","uri":"/cliffwalking/"},{"categories":["Docker"],"content":"为了进行多个容器之间通讯的实验,首先我们需要创建两个服务,分别打包成不同的镜像,并通过docker-compose进行容器编排。本次实验的项目目录如下: ├── client │ ├── dockerfile │ ├── index.html │ └── nginx.conf ├── docker-compose.yml ├── microservice1 │ ├── dockerfile │ ├── main │ └── main.go └── microservice2 ├── dockerfile ├── main └── main.go microservice后端服务定义 我们定义了两个后端服务,其代码如下: // microservice1/main.go package main import ( \"encoding/json\" \"net/http\" ) type Resp struct { Code int Message string } func main() { http.HandleFunc(\"/say_hello\", func(w http.ResponseWriter, r *http.Request) { w.Header().Set(\"Access-Control-Allow-Origin\", \"*\") //允许访问所有域 w.Header().Add(\"Access-Control-Allow-Headers\", \"Content-Type\") //header的类型 w.Header().Set(\"content-type\", \"application/json\") var data Resp if r.Method != \"GET\" { data = Resp{ Code: 4000, Message: \"Only Allow GET Method!\", } } else { data = Resp{ Code: 2000, Message: \"Hello Microservice1\", } } resp, _ := json.Marshal(data) w.Write(resp) }) http.ListenAndServe(\":8080\", nil) } 编译上述代码: GOOS=linux GOARCH=amd64 go build main.go 另一个后端服务代码如下: // microservice2/main.go package main import ( \"encoding/json\" \"net/http\" ) func main() { http.HandleFunc(\"/who_am_i\", func(w http.ResponseWriter, r *http.Request) { w.Header().Set(\"Access-Control-Allow-Origin\", \"*\") //允许访问所有域 w.Header().Add(\"Access-Control-Allow-Headers\", \"Content-Type\") //header的类型 w.Header().Set(\"content-type\", \"application/json\") data := struct{ Code int Message string }{ Code: 2000, Message: \"I am yizhigopher!\", } resp, _ := json.Marshal(data) w.Write(resp) }) http.ListenAndServe(\":8080\", nil) } 使用上述命令编译代码。 并编写容器build脚本,每个后端服务的dockerfile一样: FROM golang:1.23-alpine WORKDIR /app COPY ./main /app/microservice EXPOSE 8080 ENTRYPOINT [\"/app/microservice\"] 前端界面定义 为了直观体现出不同容器之间通讯作用,我们编写了如下前端代码: \u003c!-- client/index.html --\u003e \u003c!DOCTYPE html\u003e \u003chtml lang=\"CH-ZN\"\u003e \u003chead\u003e \u003cmeta charset=\"UTF-8\"\u003e \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e \u003cmeta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\"\u003e \u003cscript src=\"https://code.jquery.com/jquery-3.7.1.min.js\"\u003e\u003c/script\u003e \u003c/head\u003e \u003cbody\u003e \u003cbutton onclick=\"say_hello()\" style=\"width:100px; height:20px\"\u003ecall say hello\u003c/button\u003e \u003cbr/\u003e \u003cbutton onclick=\"whoami()\" style=\"width:100px; height:20px\"\u003ecall who am i\u003c/button\u003e \u003c/body\u003e \u003c/html\u003e \u003cscript\u003e function say_hello() { $.ajax({ url: \"http://localhost/api/v1/say_hello\", type: \"GET\", dataType: \"json\", async: true, success: function(res) { console.log(res) }, error: function(param) { console.log(\"fail, error=\", param) } }) } function whoami() { $.ajax({ url: \"http://localhost/api/v2/who_am_i\", type: \"GET\", dataType: \"json\", async: true, success: function(res) { console.log(res) }, error: function(param) { console.log(\"fail, error=\", param) } }) } \u003c/script\u003e 需要注意的是,其中每个接口请求的url为:http://localhost/api/v1/say_hello和http://localhost/api/v2/who_am_i。并编写nginx.conf配置代理: user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] \"$request\" ' '$status $body_bytes_sent \"$http_referer\" ' '\"$http_user_agent\" \"$http_x_forwarded_for\"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; # Server block for handling requests server { listen 80; server_name localhost; # 处理静态文件的请求(如果有) location / { root /fontend; index index.html; } location ^~/api/v1/ { proxy_pass http://router_one:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location ^~/api/v2/ { proxy_pass http://router_two:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } } 我们注意到,代理的转发路径分别是http://router_one:8080/和http://router_two:8080/,其中不是IP地址,而是容器名。 容器编排以及通信测试 编写docker-compose.yml编排内容,配置如下: version: '3' services: font_end: image: fontend:v1 build: ./client contai","date":"2024-10-29","objectID":"/docker-connection/:0:0","tags":["docker","go"],"title":"如何实现多个个容器之间的通讯","uri":"/docker-connection/"},{"categories":["golang之路"],"content":"在本节中,我们将首先简单介绍下如何安装Go语言环境,以开启Go语言学习之路!我们将简单介绍在Windows环境,Linux环境以及Mac环境下如何安装,尽可能全面的覆盖不同读者所使用的操作系统。 Go语言下载地址 Windows安装 下载windows环境下的zip文件,解压到系统的某个目录中,在我的系统中,我将其解压到本地D盘目录D:\\Program Files\\Go\\go下。 之后在系统的环境变量中将该目录下的bin目录添加到环境变量中,如图所示: 保存后通过打开终端,输入go version即可判断是否添加到环境变量中 之后需申明GOROOT、GOPATH,并将GOPATH目录下的bin目录添加到环境变量中,便于后续调用go install指令安装的命令。 Linux安装 下载图1中的源码包,删除 /usr/local/go 文件夹(如果存在),删除之前安装的 Go,然后将刚刚下载的压缩包解压缩到/usr/local,在 /usr/local/go 中创建一个全新的 GOROOT rm -rf /usr/local/go \u0026\u0026 tar -C /usr/local -xzf go1.23.2.linux-amd64.tar.gz 在PATH环境变量中添加/usr/local/go/bin,在$HOME/.profile或/etc/profile(用于全系统安装)中添加以下一行即可: export GOROOT=/usr/local/go export GOPATH=/data/go export PATH=$GOPATH/bin:$GOROOT/bin:$PATH 之后使用命令source $HOME/.profile激活环境变量配置即可。 Mac安装 安装图1中的.pkg安装文件即可 执行以下命令: cd ~ vim .bash_profile 编辑用户环境变量: export GOPATH=/Users/XXX/go #本地创建的gopath绝对路径 export PATH=$PATH:$GOPATH/bin 激活配置文件source ~/.bash_profile即可。 额外的注意点: 需要注意的是,GOPATH目录下需要创建三个文件夹,分别是src、pkg以及bin,其中bin目录保存go install安装的指令,pkg保存第三方包的源码,src用于在GO111MODULE=off时,在该路径下编写包含第三方包的程序(现在基本不在src下写代码了) 之后我们需要覆写go的几个配置: go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.cn,direct GO111MODULE是Go语言用于管理依赖关系的一种机制,它可以帮助开发者更好地管理项目的依赖包,并且可以确保项目在不同环境下的一致性 GOPROXY表示Go安装第三方包的代理(因为国内众所周知的原因),便于后续直接go get安装第三方包 至此,go的安装已经完成了 ","date":"2024-10-08","objectID":"/go-install/:0:0","tags":["golang","study"],"title":"Go语言环境安装","uri":"/go-install/"},{"categories":["vscode插件配置设置"],"content":" \"todo-tree.regex.regex\": \"((%|#|//|\u003c!--|^\\\\s*\\\\*)\\\\s*($TAGS)|^\\\\s*- \\\\[ \\\\])\", \"todo-tree.regex.regexCaseSensitive\": false, \"todo-tree.general.tags\": [ \"BUG\", \"HACK\", \"FIXME\", \"TODO\", \"todo\", \"bug\", \"tag\", \"done\", \"mark\", \"test\", \"update\", \"[]\", \"[x]\" ], \"todo-tree.highlights.defaultHighlight\": { \"background\": \"#ff9100\", \"foreground\": \"#ffffff\", \"type\": \"text\", \"icon\": \"bug\" }, \"todo-tree.highlights.customHighlight\": { //todo 需要做的功能 \"todo\": { \"icon\": \"alert\", //标签样式 \"background\": \"#c9c552\", //背景色 \"rulerColour\": \"#c9c552\", //外框颜色 \"iconColour\": \"#c9c552\", //标签颜色 }, //bug 必须要修复的BUG \"bug\": { \"background\": \"#ff3737\", \"icon\": \"bug\", \"rulerColour\": \"#eb5c5c\", \"iconColour\": \"#eb5c5c\", }, //tag 标签 \"tag\": { \"background\": \"#38b2f4\", \"icon\": \"tag\", \"rulerColour\": \"#38b2f4\", \"iconColour\": \"#38b2f4\", \"rulerLane\": \"full\" }, //done 已完成 \"done\": { \"background\": \"#328050\", \"icon\": \"check\", \"rulerColour\": \"#5eec95\", \"iconColour\": \"#5eec95\", }, //mark 标记一下 \"mark\": { \"background\": \"#f90\", \"icon\": \"note\", \"rulerColour\": \"#f90\", \"iconColour\": \"#f90\", }, //test 测试代码 \"test\": { \"background\": \"#df7be6\", \"icon\": \"flame\", \"rulerColour\": \"#df7be6\", \"iconColour\": \"#df7be6\", }, //update 优化升级点 \"update\": { \"background\": \"#b14e75\", \"icon\": \"versions\", \"rulerColour\": \"#d65d8e\", \"iconColour\": \"#d65d8e\", }, }, 将上述代码复制到settings.json中即可。 ","date":"2024-01-22","objectID":"/todotree/:0:0","tags":["vscode","extension"],"title":"Todotree插件设置","uri":"/todotree/"},{"categories":null,"content":"归一化流基本内容 什么是标准化流:基于一系列可逆变换,生成样本对应的分布 标准化流的基本原理: 变量替换:$p_x(x)=p_z(f_\\theta(x))|\\det J_{f_\\theta}(x)|$,我们可以理解为通过$z=f_\\theta(x)$,将原先复杂分布,变换成简单易懂的分布形式,其中我们要求$f_\\theta$必须是可逆变换。标准化流的目的就是求得该可逆变换。 在标准化流中,往往会使用多个这样的可逆变换,即$f_\\theta(x)=f_1(x)\\circ f_2(x)…\\circ f_K(x)$ 雅各比行列式求解: $$ \\det J_{f_\\theta}(x)=\\det \\prod_{i=1}^K J_{f_i}(x)=\\prod_{i=1}^K\\det J_{f_i}(x) $$ 利用对数函数,我们可以得到: $$ \\log p_x(x)=\\log p_z(f_{\\theta}(x))+\\sum_{i=1}^K\\log |det J_{f_i}(x)| $$ 我们需要最大化这个概率密度 ","date":"2024-01-06","objectID":"/nf-introduce/:0:1","tags":null,"title":"Normalizing Flow介绍","uri":"/nf-introduce/"},{"categories":null,"content":"论文《A deep generative model for probabilistic energy forecasting in power systems: normalizing flows》的应用: 在该论文中,作者采用标准化流的方式实现了负荷预测功能。作者利用$\\bm x$表示d-1天的负荷数据,用$\\bm c$表示天气信息,希望能够得到符合符合数据分布的分布$p_\\theta(\\bm x|\\bm c)$,从而可以利用该分布得到预测数据$^{\\bm x}$。 在利用归一化流方式对泰迪比赛数据进行负荷预测的尝试中,会进行如下操作: 提取时间数据和天气数据,重新整合原本数据格式,得到归一化流的模型输入格式 其中每一行为某个时刻的负荷数据y和影响负荷的因素(时间因素、天气因素)x。根据日期重新排列数据x,将每个时刻影响负荷的因素横向排列并组合。此时x重新排列为一个$day\\times 960$的矩阵,表现如下: ","date":"2024-01-06","objectID":"/nf-introduce/:0:2","tags":null,"title":"Normalizing Flow介绍","uri":"/nf-introduce/"},{"categories":["cuda"],"content":"创建实例 在阿里云平台上创建实例: 其中我们镜像选择为公共的Ubuntu20.04镜像,当然你也可以选择其他配置好的镜像从而简化之后的步骤。 我们之后会演示如何在一个空白的系统中,安装python、cuda以及pytorch的环境 配置好以上信息之后,我们就能获得一个实例,点击实例操作里的打开即可连接远程主机,之后我们会在这个实力上安装一些新的东西,配置我们需要的环境。 ","date":"2023-12-14","objectID":"/install/:0:1","tags":["cuda","安装教程"],"title":"阿里云PAI平台搭建pytorch-cuda11.4环境","uri":"/install/"},{"categories":["cuda"],"content":"安装基本环境 更新apt源 apt-get update 安装python 十分简单: apt-get install python3 apt-get install python3-venv apt-get install python3-pip 安装完成之后,可以执行 python3 --version 安装cuda所需环境 控制台敲入nvidia-smi获得GPU信息,可以我们所需cuda的版本是11.4 安装libxml2 apt-get install libxml2 配置好时区信息即可 安装gcc环境: apt-get install gcc-7 g++-7 配置gcc版本优先级,不然cuda无法识别到安装好的gcc update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70 --slave /usr/bin/g++ g++ /usr/bin/g++-7 --slave /usr/bin/gcov gcov /usr/bin/gcov-7 update-alternatives --config gcc 敲入gcc --version出现如下信息即可: 安装wget和vim apt-get install wget apt-get install vim 安装cuda 到nvidia官网上找到对应cuda驱动下载信息:如图选择即可 在当前目录下创建一个cuda-installer目录,进入该目录,执行installer中的命令: wget https://developer.download.nvidia.com/compute/cuda/11.4.0/local_installers/cuda_11.4.0_470.42.01_linux.run sh cuda_11.4.0_470.42.01_linux.run 敲入accpet同意协议,在之后的配置中选择如下配置: 安装即可,同时按照给出的提示: 修改/etc/profile文件,设置环境变量。使用vim /etc/profile在文末添加如下信息: export CUDA_HOME=/usr/local/cuda-11.4 export LD_LIBRARY_PATH=/usr/local/cuda-11.4/lib64:$LD_LIBRARY_PATH export PATH=/usr/local/cuda-11.4/bin:$PATH 重起实例,执行nvcc -V出现: 即可。 至此cuda安装完毕 安装Torch 去官网上,找到对应版本执行一下命令即可 pip install torch==1.12.0+cu113 torchvision==0.13.0+cu113 torchaudio==0.12.0 --extra-index-url https://download.pytorch.org/whl/cu113 ","date":"2023-12-14","objectID":"/install/:0:2","tags":["cuda","安装教程"],"title":"阿里云PAI平台搭建pytorch-cuda11.4环境","uri":"/install/"},{"categories":["golang小技巧"],"content":"简介 我们能在go代码中添加一段注释,用来表示一种编译约束 //go:build [tags] 通过这个并且配合go build -tags=\"...\"的方式,就能实现带有约束的编译。 举个例子: 我们编写一下代码:主程序申明如下 //main.go package main var configArr []string func main(){ for _, v := range configArr { print(v, \" \") } } 同时,我们会编写另外两个用于初始化的代码,分别为dev和test //go:build dev package main func init() { configArr = append(configArr, \"dev\") } //go:build test package main func init() { configArr = append(configArr, \"test\") } 我们可以看到,在两个同一包下,我们定义了两个不同的初始化功能,分别为configArr添加相应的内容。 当我们采用不同方式编译代码时,会看到如下情况: 能够看到编译时携带的tag不同,结果也就不同。 我们可以很直观的想到可以通过这种方法,实现不同模式下的编译 ","date":"2023-12-04","objectID":"/tips-1/:0:1","tags":["golang","tips"],"title":"go语言小技巧--编译约束","uri":"/tips-1/"},{"categories":["golang小技巧"],"content":"环境设置 当然我们也可以通过添加//go:build linux的方式对本段代码进行编译环境的限制。 例如我们对上述代码的go:build注释进行修改,可以看到如下效果: //go:build linux package main func init() { configArr = append(configArr, \"dev\") } //go:build windows package main func init() { configArr = append(configArr, \"test\") } 这时,我们直接进行代码编译,能够看到如下效果: 可以看到,我们只将test部分的代码编译,而dev的代码并没有编译 ","date":"2023-12-04","objectID":"/tips-1/:0:2","tags":["golang","tips"],"title":"go语言小技巧--编译约束","uri":"/tips-1/"},{"categories":["golang小技巧"],"content":"格式 举个例子:// go:build linux \u0026\u0026 amd64 \u0026\u0026 !cgo || darwin,通过这个我们就能发现,可以通过逻辑运算符来表明编译约束。 ","date":"2023-12-04","objectID":"/tips-1/:0:3","tags":["golang","tips"],"title":"go语言小技巧--编译约束","uri":"/tips-1/"},{"categories":["Docker"],"content":"如何运行容器 在之前的几篇文章中,我们学习了如何使用docker的指令以及如何进行容器打包,接下来我们就需要了解,该如何运行容器。 最简单的方式: 使用docker run或docker start指令来运行镜像或容器 但是这种方式在面对需要进行容器的端口映射、镜像卷以及容器间的网络通信时,会比较麻烦,不易操作。 同时,如果某个容器额外需要依赖另一个容器的存在,即容器之间存在关联的关系时,容器的启动顺序就比较重要了。举个简单的例子,我们手头有个web服务容器,这个容器需要依赖另一个MySQL容器的存在,这时,我们就需要先在web服务容器运行前,先运行MySQL容器。也许你会认为这种情况下,容器的先后顺序并不会对你造成困扰,但是如果容器数量多了怎么办,容器运行的相关参数特别多怎么办。亦或者经过了较长时间,你忘记了这个依赖关系怎么办? 这时候我们就需要有一个工具来管理容器运行的相关参数以及依赖关系。 ","date":"2023-11-30","objectID":"/docker-run/:0:1","tags":null,"title":"容器运行方式","uri":"/docker-run/"},{"categories":["Docker"],"content":"docker-compose工具 如何安装 Windows环境下,因为docker-desktop自带docker-compose,所以不需要关注如何安装 Linux环境下,访问docker-compose的下载地址Releases · docker/compose (github.com) ,选择适合系统的以及相应架构的可运行程序。运行sudo chmod +x docker-compose赋予其可运行能力,让后将该可执行文件放入环境变量的目录下即可 编写docker-compose.yml文件 当我们已经将容器打包完成之后,我们可以编写docker-compose.yml文件,从而能够运行容器。 我们举个简单的例子:在这个例子中,我们只需要申明其镜像卷的挂载即可 verison: '3' services: cliffwalking: image: demo:v1 container_name: reinforce_learning volumes: - /home/yizhigopher/cliffwalk/ouput:/cliffwalking/output - /home/yizhigopher/cliffwalk/model:/cliffwalking/model 我们只需要在当前docker-compose.yml的目录下,运行docker-compose up就能够运行一个名为reinforce_learning的容器,并且将容器内部的output和model文件夹的内容和容器外部的对应的文件夹相关联. 当然,docker-compose能够识别的关键字不止以上这些内容,我们可以通过访问Docker Compose overview | Docker Docs 以及菜鸟教程Docker Compose | 菜鸟教程 (runoob.com) 获得相关的更多信息.以上只是一个简单的示例,希望能够通过这些能够让读者一窥docker-compose容器编排的高效以及优越性 ","date":"2023-11-30","objectID":"/docker-run/:0:2","tags":null,"title":"容器运行方式","uri":"/docker-run/"},{"categories":["Docker"],"content":"结语 至此,docker的相关知识基本分享完毕,事实上,仅仅通过短短的三个博文是不能说明白docker的,也不可能就仅仅读这些内容就能掌握docker.这三篇博文,仅仅能够让大家对docker有个基本的了解,以及基本操作的熟悉.想要熟练掌握docker,还需要经过自己大量的实践练习和操作才能真正熟悉. ","date":"2023-11-30","objectID":"/docker-run/:0:3","tags":null,"title":"容器运行方式","uri":"/docker-run/"},{"categories":["Docker"],"content":"基本操作 在上节,我们已经安装好docker,但是就如同写代码一样,我们安装好了相关环境,但是并没有代码能够让我们运行,我们又不会写代码(自己构建镜像),那该怎么办。我们可以到github上面寻找一个相关的代码,拉取到本地,然后运行即可。 所以我们现在首先要做的事应该是学会如何拉取镜像到本地。 docker pull 完整的docker pull命令应该是:docker pull ${IMAGE_NAME}:${IMAGE_TAG} 它会从docker的官方镜像仓库中拉取对应的镜像。其中${IMAGE_TAG}部分如果不写,会默认拉取最新的镜像信息。 例如,我们现在运行docker pull hello-world命令,我们看看会发生什么: 我们能够看到,使用了最新的版本(tag),镜像的sha256验证信息,以及从哪里拉取的镜像。所以之后,如果我们需要某种镜像,我们就可以直接pull以下就可以了。 可以通过访问docker hub 上,搜索你想要的基础镜像的信息即可(这一过程需要科学上网),或者使用docker search ${IMAGE_NAME},实在不行利用bing搜索相关信息也是不错的选择 那么我们拉取完了,我们怎么能够确定这个镜像就是在我的电脑上的呢? docker images 我们在控制台输入docker images看看会发生什么: 我们看到,在我们本地存储中,确确实实有一个来自hello-world,TAG是latest的仓库的镜像。 当然你也可以通过docker inspect ${IMAGE_NAME}查看镜像在本地的哪个位置,但是这么做完全没有必要。 我们已经能够确定确确实实有个镜像在本地,那么我们该如何运行这个镜像呢 docker run 完整的docker run指令如下:docker run [OPTIONS] ${IMAGE_NAME} [COMMAND] [ARG...],这样之后会生成一个容器container 其中options常用的是: -v:绑定容器卷,后面紧跟映射关系,具体而言就是将本地文件和容器内的文件相关联。需要注意的是,两处的文件路径用:隔开,前面是本地文件的绝对路径,后面是容器内的绝对路径。例如:docker run -v /home/yizhigopher/result:/project/result xxx:v1 -d:后台运行容器,使用这个option后,我们就不会看到容器运行的结果,而只能看到一个容器ID -p:端口映射。有些时候,我们需要访问容器内的一些服务,例如MySQL容器,我们需要在本地就能连接容器中的MySQL服务,我们可以这么写:docker run -d -p 8080:3306 mysql,这样我们就是将容器内的3306端口映射到本地的8080端口,我们在本地就可以通过访问8080端口获得MySQL服务。 -i:以交互模式运行容器,通常与 -t 同时使用 -t:为容器重新分配一个伪输入终端,通常与 -i 同时使用 上述就是我们一般常用的OPTIONS信息,我们掌握了这些,基本可以应付大部分情况。如果需要其他的操作可以查阅官方文档,或者baidu。 举个例子:在终端执行docker run -it golang:alpine会发生什么: 需要注意的是我们这个命令相当于启动一个容器并进入容器内部。可以观察到,我们终端的位置发生了变化,从root@yizhigopher进入到了容器内部的/go目录下,由此也能看出docker的容器也可看成是一个小型的操作系统,在带有bash工具的容器内部,也可以执行一些简单的终端命令,例如ls、cd等等 既然我们已经学会了如何拉取镜像,如何启动一个容器,那么我们可以学学如何生成一个镜像。 ","date":"2023-11-14","objectID":"/docker-cmd/:0:1","tags":null,"title":"docker常用命令以及镜像打包","uri":"/docker-cmd/"},{"categories":["Docker"],"content":"dockerfile 要实现自己编制一个镜像,我们就得学会dockerfile文件的编写规则。 当然,由于篇幅,这里仅仅提供一些简单的dockerfile文件编写的介绍,学会了这些也就够了,更多详细的说明都可以查看官方文档。 FROM ${IMAGE_NAME} 每个dockerfile都得以FROM作为开始,我们自己构建镜像,需要在一个镜像的基础上加以创作。就如同我们平时编写代码一样,我们不可能从0101二进制串来编写代码,我们会借助编译器等基础环境来高效编写程序。 FROM ${IMAGE_NAME}的意义十分简单,你可以简答地理解为docker pull ${IMAGE_NAME},我们之后的一切操作都是在这个镜像内部执行的 WORKDIR ${FILE_NAME} 这个是自选的,WORKDIR相当于申明一个工作目录,当你的容器运行时,会默认在这个目录下运行。如果这个目录不存在,会自动帮你创建这个目录 COPY ${FILE_PATH} ${CONTAINER_FILE_PATH} 这个步骤会将本地主机下的${FILE_PATH}的内容拷贝到容器内部${CONTAINER_FILE_PATH}目录下。我们需要注意的是,如果你想拷贝一个文件,那么你需要指明这个文件在容器内部的名字,即:COPY ./requirement.txt /project/req.txt。如果你拷贝的是文件夹,那么你同样需要指明这个文件在容器内部的名称。 联系一下Linux系统下的mv指令,会有许多相同之处 需要注意的是,有一个ADD指令和COPY指令十分相似,执行的功能也大致相同,但是ADD会自动将压缩文件进行解压,而MOVE不行 RUN ${COMMAND} 这个命令会在搭建docker镜像时执行,它会执行${COMMAND}命令,通常我们用这条指令来为镜像内容进行修改。例如,我们为python代码进行打包时,会将python源代码COPY到镜像内部,然后会执行RUN pip install -r requirements.txt来安装相关包从而能够运行python代码 CMD ${COMMAND} 这个部分的命令会在容器启动时执行,需要注意的有几点 你可以写多个CMD,但是只有最后一个CMD会执行 CMD的指令会被docker run附带的运行指令覆盖 COMMND的书写格式应写成字符数组的形式,例如ls -a需写成[\"ls\", \"-a\"] ENTRYPOINT ${COMMAND} 这个指令和CMD指令十分相似,但是有一点不同,ENTRYPOINT不会被docker run后的运行指令覆盖,而是会将docker run后面的参数传递给ENTRYPOINT。具体的示例可看这个博文Docker从入门到精通——CMD与ENTRYPOINT区别 。这里就不再赘述。 ok我们大概介绍完了dockerfile需要了解的地方,现在我们来自己编写个dockerfile试试看吧。随便挑一个文件夹,将所需要的文件内容拷贝到这里,然后在这个文件夹下新建一个dockerfile文件(名字就是dockerfile),文件内容如下: 然后在这个文件夹下打开控制台,输入:docker buuild -t cliffwalk:v1 . docker build表示执行构建镜像 -t表示构建的镜像名和镜像tag为cliffwalk:v1 最后的 . 表示使用当前目录下的dockerfile 会出现: 当指令结束后,我们使用docker images就可以看到构建好的镜像信息 由于我们最后使用的是CMD来表示容器运行的指令,所以,我们可以通过docker run的方式来覆盖这条指令来进入容器内部,我们能够看到在/cliffwalking目录下,有我们COPY进去的文件内容: 至此,我们完成了docker的基本命令和镜像打包的学习,最后一章我们会介绍如何高效的启动运行容器镜像 ","date":"2023-11-14","objectID":"/docker-cmd/:0:2","tags":null,"title":"docker常用命令以及镜像打包","uri":"/docker-cmd/"},{"categories":["Docker"],"content":"什么是docker docker可以说是一门技术、一种软件,它能够帮助我们将程序进行打包,从而方便后续的项目部署以及维护。 ","date":"2023-11-14","objectID":"/docker-introduce/:0:1","tags":["docker"],"title":"docker介绍以及安装步骤说明","uri":"/docker-introduce/"},{"categories":["Docker"],"content":"为什么要用docker 场景:做项目开发的同学经常会遇到一个问题,就是这个项目能够在本地上运行,但是换一台电脑却会报各种各样的错误,这个时候不得不面对环境配置这一极其麻烦的问题 所以我们说,docker将过去的程序和系统环境的绑定关系给打破了,只要我们的电脑安装了docker,我就可以通过拉取云端的镜像,无需关注环境的搭建就可以实现跨平台的应用部署。我们不再需要面对繁杂的应用上云出现的环境搭建问题,就可以轻松地使用服务。 ","date":"2023-11-14","objectID":"/docker-introduce/:0:2","tags":["docker"],"title":"docker介绍以及安装步骤说明","uri":"/docker-introduce/"},{"categories":["Docker"],"content":"怎样安装docker 安装docker: Windows系统: 在Windows系统,我们需要确保自己的电脑安装了WSL 以管理员身份打开CMD,并敲入: wsl --install 官方文档:安装 WSL | Microsoft Learn ,可查阅官方文档获得更多的信息。 之后我们前往docker-desktop官方网站Docker Desktop: The #1 Containerization Tool for Developers | Docker 下载最新的docker-desktop即可。 需要注意的是,在使用安装好的docker-desktop之前,我们需要修改几个配置 调整docker虚拟机的位置,不然根据初始设置,会把C盘占满 修改docker的镜像源信息,不然在docker pull拉取镜像时,会特别慢: 将其中的内容替换成下述信息: { \"builder\": { \"gc\": { \"defaultKeepStorage\": \"20GB\", \"enabled\": true } }, \"experimental\": false, \"features\": { \"buildkit\": true }, \"registry-mirrors\": [ \"http://hub-mirror.c.163.com\", \"https://mirror.ccs.tencentyun.com\" ] } 或者直接修改C:\\Users\\{{ USERNAME }}\\.docker\\daemon.json内容为上述信息,重启docker。 判断是否安装成功,在CMD中,敲入: docker version 出现如下信息即可: docker之所以需要在Linux环境下使用,是源于在使用go进行编写docker时,需要借助Linux系统的Namespace和Cgroup隔离机制,所以我们在Windows上运行docker实质上是在Windows上安装了一个虚拟机WSL,在虚拟机的内部执行docker Ubuntu系统: 更新索引:sudo apt-get update 安装:sudo apt install docker.io 修改镜像源:在/etc/docker目录下创建daemon.json,在里面添加: { \"registry-mirrors\": [ \"http://hub-mirror.c.163.com\", \"https://mirror.ccs.tencentyun.com\" ] } 即可 判断是否安装成功,在终端输入:docker --version,出现 即可 CentOS/aliyun服务器: 卸载旧版(如果你之前没有安装过,可跳过这一步) yum remove docker \\ docker-client \\ docker-client-latest \\ docker-common \\ docker-latest \\ docker-latest-logrotate \\ docker-logrotate \\ docker-engine 安装依赖包:yum install -y yum-utils 为了防止是从国外的源下载,所以配置阿里云地址:yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 更新依赖:yum update 安装docker:yum install docker-ce docker-ce-cli containerd.io 配置docker镜像源:同样的在/etc/docker目录下创建daemon.json文件,填入镜像源地址信息即可。 启动docker服务:systemctl start docker 判断是否安装完成:控制台输入docker info,看到镜像源信息更改即为安装成功 当然你可以也可以在其他平台上使用docker info来判断镜像源的地址信息是否成功修改 ","date":"2023-11-14","objectID":"/docker-introduce/:0:3","tags":["docker"],"title":"docker介绍以及安装步骤说明","uri":"/docker-introduce/"},{"categories":["Docker"],"content":"一些最基本的概念 仓库Registry:你可以理解为类似代码仓库的东西,只是这里面存放的不是一段段代码,而是一堆镜像,我们可以通过一些指令来获得或上传镜像信息。 镜像Image:它是一种模板,具有创建docker容器的指令。并且一种镜像是得基于另一种镜像才能构建。我们可以把这个理解为虚拟机安装所需的iso文件,只要我有这个iso文件,我就可以打造多个一样的虚拟机环境。当然我们还可以在这个iso的基础上附带一些东西,构成一个新的iso。例如centos分为minimal(最基础的)以及desktop(带有桌面UI的),desktop就是基于minimal,同时又添加了新的东西形成的新的iso文件。 容器Container:它是一种运行实例,每个容器之间是相互隔离互不影响的。同样的,我们举个例子,当你拥有一个iso文件时,你不把它放在VMware中产生一个虚拟机实例,那么这个iso文件也就毫无用处。而你使用同一个iso文件创建的不同虚拟机之间也是不会有任何影响,你不会发现,在A虚拟机中创建了一个文件,B虚拟机中也可以找到。 如果上述的例子还是不能让你理解这三者之间的关系和实际的作用,我们可以拿日常开发做一个例子。仓库Registry就是github.com;镜像就是github.com中的pytorch项目代码,我们可以利用pytorch本身的东西创建一个新的例如predict的项目代码,当然我们也可以上传到github;容器就相当于我们执行这段代码的进程,每个进程之间不会相互影响(不考虑使用共享内存,管道等方式实现进程间的控制)。 ","date":"2023-11-14","objectID":"/docker-introduce/:0:4","tags":["docker"],"title":"docker介绍以及安装步骤说明","uri":"/docker-introduce/"},{"categories":["Docker"],"content":"总结 在这一章中,我们大概介绍了docker的一些基本信息和安装方式,在下一章我们会在ubuntu系统上介绍docker的基本操作。 ","date":"2023-11-14","objectID":"/docker-introduce/:0:5","tags":["docker"],"title":"docker介绍以及安装步骤说明","uri":"/docker-introduce/"},{"categories":null,"content":"个人介绍 出生于2002年6月,喜欢go语言,LOL的蒟蒻。 目前在华北电力大学就读软件工程本科学业。 目前正在学习强化学习,希望能够通过编写个人博客来增加我学习的动力,以及记录我学习的过程。 博客会更新什么 本科以及之后研究生学习的过程和结果 go语言相关的内容,会包括最新特性,以及我觉得有用的东西 docker应用示例,我希望通过几个简短的章节能够让你了解docker如何部署一个项目 或许还会有一些每周心得体会什么的? 我也希望能够有人在阅读我的博客之后,发送email(yizhigopher@163.com)和我交流,希望能够在各位大佬变得更强,无限进步。 ","date":"2023-11-08","objectID":"/about/:0:0","tags":null,"title":"About","uri":"/about/"},{"categories":null,"content":"这是我的第一份博客,用于测试 package main import \"fmt\" func main(){ fmt.Println(\"Hello World\") } $$ \\sum_{i=0}^{100}i = 5050 $$ ","date":"2023-11-08","objectID":"/first_post/:0:0","tags":["hugo"],"title":"First_post","uri":"/first_post/"}] \ No newline at end of file diff --git a/index.xml b/index.xml index cd4e288..e29df0c 100644 --- a/index.xml +++ b/index.xml @@ -1 +1 @@ -yizhigopher的博客http://plutolove233.github.io/变得更强,无线进步Hugo -- gohugo.iozh-CNyizhigopher@163.com (yizhigopher)yizhigopher@163.com (yizhigopher)Tue, 08 Oct 2024 15:47:15 +0800如何利用GitHub的Action实现hugo项目自动化部署http://plutolove233.github.io/workflow/Sun, 12 Nov 2023 15:39:14 +0800yizhigopherhttp://plutolove233.github.io/workflow/为什么要用Action来实现自动化部署hugo项目 不采用自动化部署,每次更新项目时,都需要在本地编译,然后上传整个public目录,比较麻烦强化学习数学知识总结http://plutolove233.github.io/concept/Fri, 10 Nov 2023 15:24:04 +0800yizhigopherhttp://plutolove233.github.io/concept/基本概念: 对于强化学习,我们一般会分成智能体(agent),环境(通过智能体的状态和动作反馈信息)两大部分,我们现在介绍一些名词,从而有利于pytorch实现线性拟合http://plutolove233.github.io/linear/Thu, 09 Nov 2023 21:59:54 +0800yizhigopherhttp://plutolove233.github.io/linear/安装pytorch 我们以英伟达显卡为例,我们需要知道自己电脑对应cuda版本信息: 在控制台输入nvidia-smi我们可以看到对应cuda版DQN算法示例:CliffWalking问题http://plutolove233.github.io/cliffwalking/Fri, 10 Nov 2023 20:48:46 +0800yizhigopherhttp://plutolove233.github.io/cliffwalking/问题描述 给定一个4×12的网格环境,如下图所示,其中黄色区域表示悬崖,我们不能经过,蓝色是我们的目标区域,我们希望能求出每个状态如何利用最少Go语言环境安装http://plutolove233.github.io/go-install/Tue, 08 Oct 2024 15:47:15 +0800yizhigopherhttp://plutolove233.github.io/go-install/在本节中,我们将首先简单介绍下如何安装Go语言环境,以开启Go语言学习之路!我们将简单介绍在Windows环境,Linux环境以及Mac环境Todotree插件设置http://plutolove233.github.io/todotree/Mon, 22 Jan 2024 14:48:37 +0800yizhigopherhttp://plutolove233.github.io/todotree/1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70Normalizing Flow介绍http://plutolove233.github.io/nf-introduce/Sat, 06 Jan 2024 14:08:15 +0800yizhigopherhttp://plutolove233.github.io/nf-introduce/归一化流基本内容 什么是标准化流:基于一系列可逆变换,生成样本对应的分布 标准化流的基本原理: 变量替换:$p_x(x)=p_z(f_\theta阿里云PAI平台搭建pytorch-cuda11.4环境http://plutolove233.github.io/install/Thu, 14 Dec 2023 15:11:01 +0800yizhigopherhttp://plutolove233.github.io/install/创建实例 在阿里云平台上创建实例: 其中我们镜像选择为公共的Ubuntu20.04镜像,当然你也可以选择其他配置好的镜像从而简化之后的步骤。 我们go语言小技巧--编译约束http://plutolove233.github.io/tips-1/Mon, 04 Dec 2023 19:13:11 +0800yizhigopherhttp://plutolove233.github.io/tips-1/简介 我们能在go代码中添加一段注释,用来表示一种编译约束 1 //go:build [tags] 通过这个并且配合go build -tags=&quot;...&quot;的方式,就能实容器运行方式http://plutolove233.github.io/docker-run/Thu, 30 Nov 2023 14:37:10 +0800yizhigopherhttp://plutolove233.github.io/docker-run/如何运行容器 在之前的几篇文章中,我们学习了如何使用docker的指令以及如何进行容器打包,接下来我们就需要了解,该如何运行容器。 最简单的方式 \ No newline at end of file +yizhigopher的博客http://plutolove233.github.io/变得更强,无线进步Hugo -- gohugo.iozh-CNyizhigopher@163.com (yizhigopher)yizhigopher@163.com (yizhigopher)Tue, 29 Oct 2024 19:44:43 +0800如何利用GitHub的Action实现hugo项目自动化部署http://plutolove233.github.io/workflow/Sun, 12 Nov 2023 15:39:14 +0800yizhigopherhttp://plutolove233.github.io/workflow/为什么要用Action来实现自动化部署hugo项目 不采用自动化部署,每次更新项目时,都需要在本地编译,然后上传整个public目录,比较麻烦强化学习数学知识总结http://plutolove233.github.io/concept/Fri, 10 Nov 2023 15:24:04 +0800yizhigopherhttp://plutolove233.github.io/concept/基本概念: 对于强化学习,我们一般会分成智能体(agent),环境(通过智能体的状态和动作反馈信息)两大部分,我们现在介绍一些名词,从而有利于pytorch实现线性拟合http://plutolove233.github.io/linear/Thu, 09 Nov 2023 21:59:54 +0800yizhigopherhttp://plutolove233.github.io/linear/安装pytorch 我们以英伟达显卡为例,我们需要知道自己电脑对应cuda版本信息: 在控制台输入nvidia-smi我们可以看到对应cuda版DQN算法示例:CliffWalking问题http://plutolove233.github.io/cliffwalking/Fri, 10 Nov 2023 20:48:46 +0800yizhigopherhttp://plutolove233.github.io/cliffwalking/问题描述 给定一个4×12的网格环境,如下图所示,其中黄色区域表示悬崖,我们不能经过,蓝色是我们的目标区域,我们希望能求出每个状态如何利用最少如何实现多个个容器之间的通讯http://plutolove233.github.io/docker-connection/Tue, 29 Oct 2024 19:44:43 +0800yizhigopherhttp://plutolove233.github.io/docker-connection/为了进行多个容器之间通讯的实验,首先我们需要创建两个服务,分别打包成不同的镜像,并通过docker-compose进行容器编排。本次实验的项Go语言环境安装http://plutolove233.github.io/go-install/Tue, 08 Oct 2024 15:47:15 +0800yizhigopherhttp://plutolove233.github.io/go-install/在本节中,我们将首先简单介绍下如何安装Go语言环境,以开启Go语言学习之路!我们将简单介绍在Windows环境,Linux环境以及Mac环境Todotree插件设置http://plutolove233.github.io/todotree/Mon, 22 Jan 2024 14:48:37 +0800yizhigopherhttp://plutolove233.github.io/todotree/1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70Normalizing Flow介绍http://plutolove233.github.io/nf-introduce/Sat, 06 Jan 2024 14:08:15 +0800yizhigopherhttp://plutolove233.github.io/nf-introduce/归一化流基本内容 什么是标准化流:基于一系列可逆变换,生成样本对应的分布 标准化流的基本原理: 变量替换:$p_x(x)=p_z(f_\theta阿里云PAI平台搭建pytorch-cuda11.4环境http://plutolove233.github.io/install/Thu, 14 Dec 2023 15:11:01 +0800yizhigopherhttp://plutolove233.github.io/install/创建实例 在阿里云平台上创建实例: 其中我们镜像选择为公共的Ubuntu20.04镜像,当然你也可以选择其他配置好的镜像从而简化之后的步骤。 我们go语言小技巧--编译约束http://plutolove233.github.io/tips-1/Mon, 04 Dec 2023 19:13:11 +0800yizhigopherhttp://plutolove233.github.io/tips-1/简介 我们能在go代码中添加一段注释,用来表示一种编译约束 1 //go:build [tags] 通过这个并且配合go build -tags=&quot;...&quot;的方式,就能实 \ No newline at end of file diff --git a/page/2/index.html b/page/2/index.html index 91dc6cc..822926e 100644 --- a/page/2/index.html +++ b/page/2/index.html @@ -14,11 +14,11 @@ -

Normalizing Flow介绍

Todotree插件设置

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

Normalizing Flow介绍

归一化流基本内容 什么是标准化流:基于一系列可逆变换,生成样本对应的分布 标准化流的基本原理: 变量替换:$p_x(x)=p_z(f_\theta

阿里云PAI平台搭建pytorch-cuda11.4环境

创建实例 在阿里云平台上创建实例: 其中我们镜像选择为公共的Ubuntu20.04镜像,当然你也可以选择其他配置好的镜像从而简化之后的步骤。 我们

go语言小技巧--编译约束

简介 我们能在go代码中添加一段注释,用来表示一种编译约束 1 //go:build [tags] 通过这个并且配合go build -tags="..."的方式,就能实

容器运行方式

如何运行容器 在之前的几篇文章中,我们学习了如何使用docker的指令以及如何进行容器打包,接下来我们就需要了解,该如何运行容器。 最简单的方式

docker常用命令以及镜像打包

基本操作 在上节,我们已经安装好docker,但是就如同写代码一样,我们安装好了相关环境,但是并没有代码能够让我们运行,我们又不会写代码(自己

docker介绍以及安装步骤说明

什么是docker docker可以说是一门技术、一种软件,它能够帮助我们将程序进行打包,从而方便后续的项目部署以及维护。 为什么要用docke
published on  Docker
基本操作 在上节,我们已经安装好docker,但是就如同写代码一样,我们安装好了相关环境,但是并没有代码能够让我们运行,我们又不会写代码(自己
Read More
\ No newline at end of file diff --git a/page/3/index.html b/page/3/index.html index bda9a0b..97baf84 100644 --- a/page/3/index.html +++ b/page/3/index.html @@ -14,6 +14,7 @@ -

First_post

docker介绍以及安装步骤说明

什么是docker docker可以说是一门技术、一种软件,它能够帮助我们将程序进行打包,从而方便后续的项目部署以及维护。 为什么要用docke

First_post

这是我的第一份博客,用于测试 1 2 3 4 5 6 7 package main import "fmt" func main(){ fmt.Println("Hello World") } $$ \sum_{i=0}^{100}i = 5050 $$
\ No newline at end of file diff --git a/posts/index.html b/posts/index.html index 56c8080..3d72baf 100644 --- a/posts/index.html +++ b/posts/index.html @@ -8,7 +8,8 @@ Cancel文章标签分类 -

All Posts

2024

All Posts

2024

2023

阿里云PAI平台搭建pytorch-cuda11.4环境 diff --git a/posts/index.xml b/posts/index.xml index b422ae8..dc1052a 100644 --- a/posts/index.xml +++ b/posts/index.xml @@ -1 +1 @@ -All Posts - yizhigopher的博客http://plutolove233.github.io/posts/All Posts | yizhigopher的博客Hugo -- gohugo.iozh-CNyizhigopher@163.com (yizhigopher)yizhigopher@163.com (yizhigopher)Tue, 08 Oct 2024 15:47:15 +0800如何利用GitHub的Action实现hugo项目自动化部署http://plutolove233.github.io/workflow/Sun, 12 Nov 2023 15:39:14 +0800yizhigopherhttp://plutolove233.github.io/workflow/为什么要用Action来实现自动化部署hugo项目 不采用自动化部署,每次更新项目时,都需要在本地编译,然后上传整个public目录,比较麻烦强化学习数学知识总结http://plutolove233.github.io/concept/Fri, 10 Nov 2023 15:24:04 +0800yizhigopherhttp://plutolove233.github.io/concept/基本概念: 对于强化学习,我们一般会分成智能体(agent),环境(通过智能体的状态和动作反馈信息)两大部分,我们现在介绍一些名词,从而有利于pytorch实现线性拟合http://plutolove233.github.io/linear/Thu, 09 Nov 2023 21:59:54 +0800yizhigopherhttp://plutolove233.github.io/linear/安装pytorch 我们以英伟达显卡为例,我们需要知道自己电脑对应cuda版本信息: 在控制台输入nvidia-smi我们可以看到对应cuda版DQN算法示例:CliffWalking问题http://plutolove233.github.io/cliffwalking/Fri, 10 Nov 2023 20:48:46 +0800yizhigopherhttp://plutolove233.github.io/cliffwalking/问题描述 给定一个4×12的网格环境,如下图所示,其中黄色区域表示悬崖,我们不能经过,蓝色是我们的目标区域,我们希望能求出每个状态如何利用最少Go语言环境安装http://plutolove233.github.io/go-install/Tue, 08 Oct 2024 15:47:15 +0800yizhigopherhttp://plutolove233.github.io/go-install/在本节中,我们将首先简单介绍下如何安装Go语言环境,以开启Go语言学习之路!我们将简单介绍在Windows环境,Linux环境以及Mac环境Todotree插件设置http://plutolove233.github.io/todotree/Mon, 22 Jan 2024 14:48:37 +0800yizhigopherhttp://plutolove233.github.io/todotree/1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70Normalizing Flow介绍http://plutolove233.github.io/nf-introduce/Sat, 06 Jan 2024 14:08:15 +0800yizhigopherhttp://plutolove233.github.io/nf-introduce/归一化流基本内容 什么是标准化流:基于一系列可逆变换,生成样本对应的分布 标准化流的基本原理: 变量替换:$p_x(x)=p_z(f_\theta阿里云PAI平台搭建pytorch-cuda11.4环境http://plutolove233.github.io/install/Thu, 14 Dec 2023 15:11:01 +0800yizhigopherhttp://plutolove233.github.io/install/创建实例 在阿里云平台上创建实例: 其中我们镜像选择为公共的Ubuntu20.04镜像,当然你也可以选择其他配置好的镜像从而简化之后的步骤。 我们go语言小技巧--编译约束http://plutolove233.github.io/tips-1/Mon, 04 Dec 2023 19:13:11 +0800yizhigopherhttp://plutolove233.github.io/tips-1/简介 我们能在go代码中添加一段注释,用来表示一种编译约束 1 //go:build [tags] 通过这个并且配合go build -tags=&quot;...&quot;的方式,就能实容器运行方式http://plutolove233.github.io/docker-run/Thu, 30 Nov 2023 14:37:10 +0800yizhigopherhttp://plutolove233.github.io/docker-run/如何运行容器 在之前的几篇文章中,我们学习了如何使用docker的指令以及如何进行容器打包,接下来我们就需要了解,该如何运行容器。 最简单的方式 \ No newline at end of file +All Posts - yizhigopher的博客http://plutolove233.github.io/posts/All Posts | yizhigopher的博客Hugo -- gohugo.iozh-CNyizhigopher@163.com (yizhigopher)yizhigopher@163.com (yizhigopher)Tue, 29 Oct 2024 19:44:43 +0800如何利用GitHub的Action实现hugo项目自动化部署http://plutolove233.github.io/workflow/Sun, 12 Nov 2023 15:39:14 +0800yizhigopherhttp://plutolove233.github.io/workflow/为什么要用Action来实现自动化部署hugo项目 不采用自动化部署,每次更新项目时,都需要在本地编译,然后上传整个public目录,比较麻烦强化学习数学知识总结http://plutolove233.github.io/concept/Fri, 10 Nov 2023 15:24:04 +0800yizhigopherhttp://plutolove233.github.io/concept/基本概念: 对于强化学习,我们一般会分成智能体(agent),环境(通过智能体的状态和动作反馈信息)两大部分,我们现在介绍一些名词,从而有利于pytorch实现线性拟合http://plutolove233.github.io/linear/Thu, 09 Nov 2023 21:59:54 +0800yizhigopherhttp://plutolove233.github.io/linear/安装pytorch 我们以英伟达显卡为例,我们需要知道自己电脑对应cuda版本信息: 在控制台输入nvidia-smi我们可以看到对应cuda版DQN算法示例:CliffWalking问题http://plutolove233.github.io/cliffwalking/Fri, 10 Nov 2023 20:48:46 +0800yizhigopherhttp://plutolove233.github.io/cliffwalking/问题描述 给定一个4×12的网格环境,如下图所示,其中黄色区域表示悬崖,我们不能经过,蓝色是我们的目标区域,我们希望能求出每个状态如何利用最少如何实现多个个容器之间的通讯http://plutolove233.github.io/docker-connection/Tue, 29 Oct 2024 19:44:43 +0800yizhigopherhttp://plutolove233.github.io/docker-connection/为了进行多个容器之间通讯的实验,首先我们需要创建两个服务,分别打包成不同的镜像,并通过docker-compose进行容器编排。本次实验的项Go语言环境安装http://plutolove233.github.io/go-install/Tue, 08 Oct 2024 15:47:15 +0800yizhigopherhttp://plutolove233.github.io/go-install/在本节中,我们将首先简单介绍下如何安装Go语言环境,以开启Go语言学习之路!我们将简单介绍在Windows环境,Linux环境以及Mac环境Todotree插件设置http://plutolove233.github.io/todotree/Mon, 22 Jan 2024 14:48:37 +0800yizhigopherhttp://plutolove233.github.io/todotree/1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70Normalizing Flow介绍http://plutolove233.github.io/nf-introduce/Sat, 06 Jan 2024 14:08:15 +0800yizhigopherhttp://plutolove233.github.io/nf-introduce/归一化流基本内容 什么是标准化流:基于一系列可逆变换,生成样本对应的分布 标准化流的基本原理: 变量替换:$p_x(x)=p_z(f_\theta阿里云PAI平台搭建pytorch-cuda11.4环境http://plutolove233.github.io/install/Thu, 14 Dec 2023 15:11:01 +0800yizhigopherhttp://plutolove233.github.io/install/创建实例 在阿里云平台上创建实例: 其中我们镜像选择为公共的Ubuntu20.04镜像,当然你也可以选择其他配置好的镜像从而简化之后的步骤。 我们go语言小技巧--编译约束http://plutolove233.github.io/tips-1/Mon, 04 Dec 2023 19:13:11 +0800yizhigopherhttp://plutolove233.github.io/tips-1/简介 我们能在go代码中添加一段注释,用来表示一种编译约束 1 //go:build [tags] 通过这个并且配合go build -tags=&quot;...&quot;的方式,就能实 \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 8211f06..25f9be8 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1 +1 @@ -http://plutolove233.github.io/workflow/2023-11-12T15:39:14+08:00weekly0.5http://plutolove233.github.io/concept/2023-11-10T15:24:04+08:00weekly0.5http://plutolove233.github.io/linear/2023-11-09T21:59:54+08:00weekly0.5http://plutolove233.github.io/cliffwalking/2023-11-10T20:48:46+08:00weekly0.5http://plutolove233.github.io/categories/2024-10-08T15:47:15+08:00weekly0.9http://plutolove233.github.io/tags/golang/2024-10-08T15:47:15+08:00weekly0.9http://plutolove233.github.io/categories/golang%E4%B9%8B%E8%B7%AF/2024-10-08T15:47:15+08:00weekly0.9http://plutolove233.github.io/go-install/2024-10-08T15:47:15+08:00weekly0.9http://plutolove233.github.io/posts/2024-10-08T15:47:15+08:00weekly0.9http://plutolove233.github.io/tags/study/2024-10-08T15:47:15+08:00weekly0.9http://plutolove233.github.io/tags/2024-10-08T15:47:15+08:00weekly0.9http://plutolove233.github.io/2024-10-08T15:47:15+08:00weekly0.9http://plutolove233.github.io/tags/extension/2024-01-22T14:48:37+08:00weekly0.5http://plutolove233.github.io/todotree/2024-01-22T14:48:37+08:00weekly0.5http://plutolove233.github.io/tags/vscode/2024-01-22T14:48:37+08:00weekly0.5http://plutolove233.github.io/categories/vscode%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE%E8%AE%BE%E7%BD%AE/2024-01-22T14:48:37+08:00weekly0.5http://plutolove233.github.io/nf-introduce/2024-01-06T14:08:15+08:00weekly0.5http://plutolove233.github.io/tags/cuda/2023-12-14T15:11:01+08:00weekly0.5http://plutolove233.github.io/categories/cuda/2023-12-14T15:11:01+08:00weekly0.5http://plutolove233.github.io/tags/%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/2023-12-14T15:11:01+08:00weekly0.5http://plutolove233.github.io/install/2023-12-14T15:11:01+08:00weekly0.5http://plutolove233.github.io/categories/golang%E5%B0%8F%E6%8A%80%E5%B7%A7/2023-12-04T19:13:11+08:00weekly0.5http://plutolove233.github.io/tips-1/2023-12-04T19:13:11+08:00weekly0.5http://plutolove233.github.io/tags/tips/2023-12-04T19:13:11+08:00weekly0.5http://plutolove233.github.io/categories/docker/2023-11-30T14:37:10+08:00weekly0.5http://plutolove233.github.io/docker-run/2023-11-30T14:37:10+08:00weekly0.5http://plutolove233.github.io/docker-cmd/2023-11-14T21:11:15+08:00weekly0.5http://plutolove233.github.io/tags/docker/2023-11-14T19:45:12+08:00weekly0.5http://plutolove233.github.io/docker-introduce/2023-11-14T19:45:12+08:00weekly0.5http://plutolove233.github.io/tags/github/2023-11-12T15:39:14+08:00weekly0.5http://plutolove233.github.io/categories/hugo/2023-11-12T15:39:14+08:00weekly0.5http://plutolove233.github.io/tags/%E8%87%AA%E5%8A%A8%E5%8C%96%E9%83%A8%E7%BD%B2/2023-11-12T15:39:14+08:00weekly0.5http://plutolove233.github.io/tags/dqn/2023-11-10T20:48:46+08:00weekly0.5http://plutolove233.github.io/tags/pytorch/2023-11-10T20:48:46+08:00weekly0.5http://plutolove233.github.io/tags/rl/2023-11-10T20:48:46+08:00weekly0.5http://plutolove233.github.io/categories/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B9%8B%E8%B7%AF/2023-11-10T20:48:46+08:00weekly0.5http://plutolove233.github.io/tags/math/2023-11-10T15:24:04+08:00weekly0.5http://plutolove233.github.io/tags/mechine-learning/2023-11-09T21:59:54+08:00weekly0.5http://plutolove233.github.io/about/2023-11-08T18:58:39+08:00weekly0.5http://plutolove233.github.io/first_post/2023-11-08T18:18:13+08:00weekly0.5http://plutolove233.github.io/tags/hugo/2023-11-08T18:18:13+08:00weekly0.5 \ No newline at end of file +http://plutolove233.github.io/workflow/2023-11-12T15:39:14+08:00weekly0.5http://plutolove233.github.io/concept/2023-11-10T15:24:04+08:00weekly0.5http://plutolove233.github.io/linear/2023-11-09T21:59:54+08:00weekly0.5http://plutolove233.github.io/cliffwalking/2023-11-10T20:48:46+08:00weekly0.5http://plutolove233.github.io/categories/2024-10-29T19:44:43+08:00weekly1http://plutolove233.github.io/tags/docker/2024-10-29T19:44:43+08:00weekly1http://plutolove233.github.io/categories/docker/2024-10-29T19:44:43+08:00weekly1http://plutolove233.github.io/tags/go/2024-10-29T19:44:43+08:00weekly1http://plutolove233.github.io/posts/2024-10-29T19:44:43+08:00weekly1http://plutolove233.github.io/tags/2024-10-29T19:44:43+08:00weekly1http://plutolove233.github.io/2024-10-29T19:44:43+08:00weekly1http://plutolove233.github.io/docker-connection/2024-10-29T19:44:43+08:00weekly1http://plutolove233.github.io/tags/golang/2024-10-08T15:47:15+08:00weekly0.7http://plutolove233.github.io/categories/golang%E4%B9%8B%E8%B7%AF/2024-10-08T15:47:15+08:00weekly0.7http://plutolove233.github.io/go-install/2024-10-08T15:47:15+08:00weekly0.7http://plutolove233.github.io/tags/study/2024-10-08T15:47:15+08:00weekly0.7http://plutolove233.github.io/tags/extension/2024-01-22T14:48:37+08:00weekly0.5http://plutolove233.github.io/todotree/2024-01-22T14:48:37+08:00weekly0.5http://plutolove233.github.io/tags/vscode/2024-01-22T14:48:37+08:00weekly0.5http://plutolove233.github.io/categories/vscode%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE%E8%AE%BE%E7%BD%AE/2024-01-22T14:48:37+08:00weekly0.5http://plutolove233.github.io/nf-introduce/2024-01-06T14:08:15+08:00weekly0.5http://plutolove233.github.io/tags/cuda/2023-12-14T15:11:01+08:00weekly0.5http://plutolove233.github.io/categories/cuda/2023-12-14T15:11:01+08:00weekly0.5http://plutolove233.github.io/tags/%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/2023-12-14T15:11:01+08:00weekly0.5http://plutolove233.github.io/install/2023-12-14T15:11:01+08:00weekly0.5http://plutolove233.github.io/categories/golang%E5%B0%8F%E6%8A%80%E5%B7%A7/2023-12-04T19:13:11+08:00weekly0.5http://plutolove233.github.io/tips-1/2023-12-04T19:13:11+08:00weekly0.5http://plutolove233.github.io/tags/tips/2023-12-04T19:13:11+08:00weekly0.5http://plutolove233.github.io/docker-run/2023-11-30T14:37:10+08:00weekly0.5http://plutolove233.github.io/docker-cmd/2023-11-14T21:11:15+08:00weekly0.5http://plutolove233.github.io/docker-introduce/2023-11-14T19:45:12+08:00weekly0.5http://plutolove233.github.io/tags/github/2023-11-12T15:39:14+08:00weekly0.5http://plutolove233.github.io/categories/hugo/2023-11-12T15:39:14+08:00weekly0.5http://plutolove233.github.io/tags/%E8%87%AA%E5%8A%A8%E5%8C%96%E9%83%A8%E7%BD%B2/2023-11-12T15:39:14+08:00weekly0.5http://plutolove233.github.io/tags/dqn/2023-11-10T20:48:46+08:00weekly0.5http://plutolove233.github.io/tags/pytorch/2023-11-10T20:48:46+08:00weekly0.5http://plutolove233.github.io/tags/rl/2023-11-10T20:48:46+08:00weekly0.5http://plutolove233.github.io/categories/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B9%8B%E8%B7%AF/2023-11-10T20:48:46+08:00weekly0.5http://plutolove233.github.io/tags/math/2023-11-10T15:24:04+08:00weekly0.5http://plutolove233.github.io/tags/mechine-learning/2023-11-09T21:59:54+08:00weekly0.5http://plutolove233.github.io/about/2023-11-08T18:58:39+08:00weekly0.5http://plutolove233.github.io/first_post/2023-11-08T18:18:13+08:00weekly0.5http://plutolove233.github.io/tags/hugo/2023-11-08T18:18:13+08:00weekly0.5 \ No newline at end of file diff --git a/tags/docker/index.html b/tags/docker/index.html index 024d86a..5e9e587 100644 --- a/tags/docker/index.html +++ b/tags/docker/index.html @@ -8,6 +8,7 @@
Cancel
文章标签分类 -
\ No newline at end of file diff --git a/tags/docker/index.xml b/tags/docker/index.xml index 6809df5..bc18f95 100644 --- a/tags/docker/index.xml +++ b/tags/docker/index.xml @@ -1 +1 @@ -docker - Tag - yizhigopher的博客http://plutolove233.github.io/tags/docker/docker - Tag - yizhigopher的博客Hugo -- gohugo.iozh-CNyizhigopher@163.com (yizhigopher)yizhigopher@163.com (yizhigopher)Tue, 14 Nov 2023 19:45:12 +0800docker介绍以及安装步骤说明http://plutolove233.github.io/docker-introduce/Tue, 14 Nov 2023 19:45:12 +0800yizhigopherhttp://plutolove233.github.io/docker-introduce/什么是docker docker可以说是一门技术、一种软件,它能够帮助我们将程序进行打包,从而方便后续的项目部署以及维护。 为什么要用docke \ No newline at end of file +docker - Tag - yizhigopher的博客http://plutolove233.github.io/tags/docker/docker - Tag - yizhigopher的博客Hugo -- gohugo.iozh-CNyizhigopher@163.com (yizhigopher)yizhigopher@163.com (yizhigopher)Tue, 29 Oct 2024 19:44:43 +0800如何实现多个个容器之间的通讯http://plutolove233.github.io/docker-connection/Tue, 29 Oct 2024 19:44:43 +0800yizhigopherhttp://plutolove233.github.io/docker-connection/为了进行多个容器之间通讯的实验,首先我们需要创建两个服务,分别打包成不同的镜像,并通过docker-compose进行容器编排。本次实验的项docker介绍以及安装步骤说明http://plutolove233.github.io/docker-introduce/Tue, 14 Nov 2023 19:45:12 +0800yizhigopherhttp://plutolove233.github.io/docker-introduce/什么是docker docker可以说是一门技术、一种软件,它能够帮助我们将程序进行打包,从而方便后续的项目部署以及维护。 为什么要用docke \ No newline at end of file diff --git a/tags/go/index.html b/tags/go/index.html new file mode 100644 index 0000000..47d14c9 --- /dev/null +++ b/tags/go/index.html @@ -0,0 +1,13 @@ +go - Tag - yizhigopher的博客 +
\ No newline at end of file diff --git a/tags/go/index.xml b/tags/go/index.xml new file mode 100644 index 0000000..f8a9ee8 --- /dev/null +++ b/tags/go/index.xml @@ -0,0 +1 @@ +go - Tag - yizhigopher的博客http://plutolove233.github.io/tags/go/go - Tag - yizhigopher的博客Hugo -- gohugo.iozh-CNyizhigopher@163.com (yizhigopher)yizhigopher@163.com (yizhigopher)Tue, 29 Oct 2024 19:44:43 +0800如何实现多个个容器之间的通讯http://plutolove233.github.io/docker-connection/Tue, 29 Oct 2024 19:44:43 +0800yizhigopherhttp://plutolove233.github.io/docker-connection/为了进行多个容器之间通讯的实验,首先我们需要创建两个服务,分别打包成不同的镜像,并通过docker-compose进行容器编排。本次实验的项 \ No newline at end of file diff --git a/tags/go/page/1/index.html b/tags/go/page/1/index.html new file mode 100644 index 0000000..a32bd8d --- /dev/null +++ b/tags/go/page/1/index.html @@ -0,0 +1,2 @@ +http://plutolove233.github.io/tags/go/ + \ No newline at end of file diff --git a/tags/index.html b/tags/index.html index 53060c0..93bd03c 100644 --- a/tags/index.html +++ b/tags/index.html @@ -8,5 +8,5 @@ Cancel文章标签分类 -
\ No newline at end of file diff --git a/tags/index.xml b/tags/index.xml index 7c4cdc5..eb048c5 100644 --- a/tags/index.xml +++ b/tags/index.xml @@ -1 +1 @@ -Tags - Tag - yizhigopher的博客http://plutolove233.github.io/tags/Tags - Tag - yizhigopher的博客Hugo -- gohugo.iozh-CNyizhigopher@163.com (yizhigopher)yizhigopher@163.com (yizhigopher)Tue, 08 Oct 2024 15:47:15 +0800golanghttp://plutolove233.github.io/tags/golang/Tue, 08 Oct 2024 15:47:15 +0800yizhigopherhttp://plutolove233.github.io/tags/golang/studyhttp://plutolove233.github.io/tags/study/Tue, 08 Oct 2024 15:47:15 +0800yizhigopherhttp://plutolove233.github.io/tags/study/extensionhttp://plutolove233.github.io/tags/extension/Mon, 22 Jan 2024 14:48:37 +0800yizhigopherhttp://plutolove233.github.io/tags/extension/vscodehttp://plutolove233.github.io/tags/vscode/Mon, 22 Jan 2024 14:48:37 +0800yizhigopherhttp://plutolove233.github.io/tags/vscode/cudahttp://plutolove233.github.io/tags/cuda/Thu, 14 Dec 2023 15:11:01 +0800yizhigopherhttp://plutolove233.github.io/tags/cuda/安装教程http://plutolove233.github.io/tags/%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/Thu, 14 Dec 2023 15:11:01 +0800yizhigopherhttp://plutolove233.github.io/tags/%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/tipshttp://plutolove233.github.io/tags/tips/Mon, 04 Dec 2023 19:13:11 +0800yizhigopherhttp://plutolove233.github.io/tags/tips/dockerhttp://plutolove233.github.io/tags/docker/Tue, 14 Nov 2023 19:45:12 +0800yizhigopherhttp://plutolove233.github.io/tags/docker/githubhttp://plutolove233.github.io/tags/github/Sun, 12 Nov 2023 15:39:14 +0800yizhigopherhttp://plutolove233.github.io/tags/github/自动化部署http://plutolove233.github.io/tags/%E8%87%AA%E5%8A%A8%E5%8C%96%E9%83%A8%E7%BD%B2/Sun, 12 Nov 2023 15:39:14 +0800yizhigopherhttp://plutolove233.github.io/tags/%E8%87%AA%E5%8A%A8%E5%8C%96%E9%83%A8%E7%BD%B2/ \ No newline at end of file +Tags - Tag - yizhigopher的博客http://plutolove233.github.io/tags/Tags - Tag - yizhigopher的博客Hugo -- gohugo.iozh-CNyizhigopher@163.com (yizhigopher)yizhigopher@163.com (yizhigopher)Tue, 29 Oct 2024 19:44:43 +0800dockerhttp://plutolove233.github.io/tags/docker/Tue, 29 Oct 2024 19:44:43 +0800yizhigopherhttp://plutolove233.github.io/tags/docker/gohttp://plutolove233.github.io/tags/go/Tue, 29 Oct 2024 19:44:43 +0800yizhigopherhttp://plutolove233.github.io/tags/go/golanghttp://plutolove233.github.io/tags/golang/Tue, 08 Oct 2024 15:47:15 +0800yizhigopherhttp://plutolove233.github.io/tags/golang/studyhttp://plutolove233.github.io/tags/study/Tue, 08 Oct 2024 15:47:15 +0800yizhigopherhttp://plutolove233.github.io/tags/study/extensionhttp://plutolove233.github.io/tags/extension/Mon, 22 Jan 2024 14:48:37 +0800yizhigopherhttp://plutolove233.github.io/tags/extension/vscodehttp://plutolove233.github.io/tags/vscode/Mon, 22 Jan 2024 14:48:37 +0800yizhigopherhttp://plutolove233.github.io/tags/vscode/cudahttp://plutolove233.github.io/tags/cuda/Thu, 14 Dec 2023 15:11:01 +0800yizhigopherhttp://plutolove233.github.io/tags/cuda/安装教程http://plutolove233.github.io/tags/%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/Thu, 14 Dec 2023 15:11:01 +0800yizhigopherhttp://plutolove233.github.io/tags/%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/tipshttp://plutolove233.github.io/tags/tips/Mon, 04 Dec 2023 19:13:11 +0800yizhigopherhttp://plutolove233.github.io/tags/tips/githubhttp://plutolove233.github.io/tags/github/Sun, 12 Nov 2023 15:39:14 +0800yizhigopherhttp://plutolove233.github.io/tags/github/ \ No newline at end of file