长恨此身非我有

Posted on Sun 26 May 2024 in Journal

Abstract 长恨此身非我有
Authors Walter Fan
 Category    learning note  
Status v1.0
Updated 2024-05-26
License CC-BY-NC-ND 4.0

我的偶像苏东坡写过一首词 - 临江仙

夜饮东坡醒复醉,归来仿佛三更。家童鼻息已雷鸣。敲门都不应,倚杖听江声。 长恨此身非我有,何时忘却营营。夜阑风静縠纹平。小舟从此逝,江海寄余生。

张爱玲在《半生缘》里写道:“中年以后的男人,时常会觉得孤独,因为他一睁开眼睛,周围都是要依靠他的人,却没有他可以依靠的人。 这句话, 我不是太认同, 依靠其实是互相的, 有人需要依靠你, 是一种幸福, 你在生活和情感上也在依靠他们。

此身非我有, 这是一种常态, 你不能只为你自己活着, 你得为家人拼搏, 为了生活, 你不能随心所欲, 你不能随便讲话, 你不能针砭时弊, 你不能得罪他人, 你不能放松学习, 你不能... 你只能在自己的博客上发发牢骚.

人生就是这样, 不如意之事十之八九, 就象罗曼罗兰说的, 认清生活的真相, 依然热爱生活, 才是真正的英雄.

tips

预测机与分类器

预测机(Predictor)和分类器(Classifier)是机器学习领域中的两种常见模型,它们用于处理不同类型的预测问题。

  1. 预测机
  2. 预测机是一种用于预测连续值输出的模型。换句话说,它预测的是一个数值范围,而不是一个具体的类别。
  3. 预测机通常用于回归问题(Regression Problems),例如房价预测、股票价格预测、温度预测等。
  4. 常见的预测机算法包括线性回归(Linear Regression)、支持向量回归(Support Vector Regression, SVR)、决策树回归(Decision Tree Regression)等。

  5. 分类器

  6. 分类器是一种用于预测离散值输出的模型。它预测的是数据属于哪个类别或标签。
  7. 分类器通常用于分类问题(Classification Problems),例如垃圾邮件检测、疾病诊断、图像识别等。
  8. 常见的分类器算法包括逻辑回归(Logistic Regression)、决策树(Decision Trees)、随机森林(Random Forests)、支持向量机(Support Vector Machines, SVM)、神经网络(Neural Networks)等。

两者的主要区别在于预测的目标类型不同:预测机预测连续值,而分类器预测离散值。在实际应用中,选择哪种模型取决于问题的性质和数据的特点。

sigmoid 函数的妙用

Sigmoid 函数是一种数学函数,它在机器学习和深度学习中非常有用,尤其是在二分类问题中。Sigmoid 函数的数学表达式如下:

[ \sigma(x) = \frac{1}{1 + e^{-x}} ]

其中 ( x ) 是输入值,( e ) 是自然对数的底数(约等于 2.71828),而 ( \sigma(x) ) 是输出值。

Sigmoid 函数有以下特点:

  1. 输出范围:Sigmoid 函数的输出值介于 0 和 1 之间,这使得它非常适合用作二分类问题中的激活函数,因为它可以输出一个概率值,表示某个类别的可能性。

  2. 平滑曲线:Sigmoid 函数是一个连续且平滑的曲线,它在 ( x ) 接近正无穷时趋近于 1,在 ( x ) 接近负无穷时趋近于 0。

  3. 非线性:Sigmoid 函数是一个非线性函数,这使得它能够处理非线性问题。

  4. 中心对称:Sigmoid 函数关于 ( x = 0 ) 对称,这意味着正的和负的输入值在函数图像上是对称的。

  5. 梯度消失问题:Sigmoid 函数在输入值非常大或非常小的时候,梯度接近于 0,这会导致在反向传播过程中的梯度消失问题,使得训练深度神经网络时难以学习。

尽管 Sigmoid 函数在某些情况下非常有用,但在现代深度学习中,ReLU(Rectified Linear Unit)及其变体由于其计算效率和避免梯度消失问题的特性,更常被用作隐藏层的激活函数。然而,Sigmoid 函数仍然广泛用于输出层,特别是在二分类问题中,因为它能够输出一个介于 0 和 1 之间的值,可以解释为概率。

notes

Go语言的赋值、分支和循环语句是编程中的基本组成部分。下面是这些语句的基本语法和用法:

赋值语句

在Go语言中,赋值语句使用=运算符。它将右侧表达式的值赋给左侧的变量。Go语言支持并行赋值,即一次可以给多个变量赋值。

// 单变量赋值
var x int
x = 10

// 并行赋值
var a, b int
a, b = 1, 2

分支语句

Go语言的分支语句主要包括ifswitch

if 语句

if语句用于基于条件执行代码块。

if x > 10 {
    fmt.Println("x is greater than 10")
} else {
    fmt.Println("x is less than or equal to 10")
}

if语句也可以与简短的初始化语句结合使用。

if x := computeX(); x > 10 {
    fmt.Println("x is greater than 10")
}

switch 语句

switch语句是一种多路选择结构,类似于其他语言的switchcase语句。

switch os := runtime.GOOS; os {
    case "darwin":
        fmt.Println("OS X.")
    case "linux":
        fmt.Println("Linux.")
    default:
        fmt.Printf("%s.\n", os)
}

循环语句

Go语言的循环语句主要包括for循环。

for 循环

Go语言中的for循环是最常用的循环结构,可以用于迭代数组、切片、映射、通道等。

// 传统for循环
for i := 0; i < 10; i++ {
    fmt.Println(i)
}

// 无限循环
for {
    fmt.Println("无限循环")
}

// 基于范围的for循环
arr := []int{1, 2, 3, 4, 5}
for _, value := range arr {
    fmt.Println(value)
}

Go语言没有while循环,但可以使用for循环来实现相同的功能。

// 相当于while循环
for x < 10 {
    // 执行代码
    x++
}

写一个简单的 REST API service

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "strconv"
)

// User 结构体定义了用户的数据结构
type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

// users 模拟数据库存储用户信息
var users = []User{}

// getUsers 处理GET请求,列出所有用户
func getUsers(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(users)
}

// getUser 处理GET请求,根据ID获取单个用户
func getUser(w http.ResponseWriter, r *http.Request) {
    id, _ := strconv.Atoi((r.URL).Query().Get(":id"))
    for _, user := range users {
        if user.ID == id {
            json.NewEncoder(w).Encode(user)
            return
        }
    }
    w.WriteHeader(http.StatusNotFound)
    fmt.Fprintf(w, "用户ID %d 不存在\n", id)
}

// createUser 处理POST请求,创建新用户
func createUser(w http.ResponseWriter, r *http.Request) {
    var user User
    json.NewDecoder(r.Body).Decode(&user)
    users = append(users, user)
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(user)
}

// updateUser 处理PUT请求,更新用户信息
func updateUser(w http.ResponseWriter, r *http.Request) {
    id, _ := strconv.Atoi((r.URL).Query().Get(":id"))
    var user User
    json.NewDecoder(r.Body).Decode(&user)

    for i, u := range users {
        if u.ID == id {
            users[i] = user
            json.NewEncoder(w).Encode(user)
            return
        }
    }
    w.WriteHeader(http.StatusNotFound)
    fmt.Fprintf(w, "用户ID %d 不存在\n", id)
}

// deleteUser 处理DELETE请求,删除用户
func deleteUser(w http.ResponseWriter, r *http.Request) {
    id, _ := strconv.Atoi((r.URL).Query().Get(":id"))

    for i, u := range users {
        if u.ID == id {
            users = append(users[:i], users[i+1:]...)
            w.WriteHeader(http.StatusOK)
            fmt.Fprintf(w, "用户ID %d 删除成功\n", id)
            return
        }
    }
    w.WriteHeader(http.StatusNotFound)
    fmt.Fprintf(w, "用户ID %d 不存在\n", id)
}

func main() {
    http.HandleFunc("/users", getUsers)
    http.HandleFunc("/users/:id", getUser)
    http.HandleFunc("/users", createUser)
    http.HandleFunc("/users/:id", updateUser)
    http.HandleFunc("/users/:id", deleteUser)

    port := "8080"
    log.Printf("服务器正在监听端口: %s", port)
    log.Fatal(http.ListenAndServe(":"+port, nil))
}

本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。