> 2021年09月13日信息消化 ### 机器学习 Week 7 Optimization Objective #### Support vector machine SVM: 用近似向量去替代原logistic regression的成本函数。  因为是取min值所以1/m可以直接去掉。 成本函数的正规化trade-off, A+ $\lambda$B → CA + B.  ###### 随堂小测  #### SVM: Large margin classifier SVM会取离训练样本**margin**最大的方案。  ###### 随堂小测  #### Mathematics Behind Large Margin Classification  ###### 随堂小测 最近的练样本在$\theta$向量上的映射≈2,要满足成本函数($||\theta||・p^{(i)} \lt 1$) 同时取民,所以取1/2。  ### Geometry Introduction https://quivergeometry.net/ This site describes an ongoing project to build a **totally discrete framework for geometry**, using elementary ideas from a range of mathematical fields, including graph theory, group theory, representation theory, computer science, differential geometry, calculus, abstract rewriting systems, and others. It asks the question: how are we to think about a geometry that has a fundamentally smallest scale? While it doesn’t make immediate connections to physics, it does aim to populate the toolbox of ideas and methods we might use to build and analyze models of fundamental physics that *are* discrete, finite, and computable. 这个网站描述了一个正在进行的项目,旨在建立一个**完全离散的几何框架**,使用来自一系列数学领域的基本思想,包括图论、群论、表示理论、计算机科学、微分几何、微积分、抽象重写系统等。它提出了一个问题:我们该如何思考一个从根本上说具有最小尺度的几何学?虽然它没有与物理学建立直接的联系,但它确实旨在充实我们可能用来建立和分析*是离散的、有限的和可计算的基本物理学模型的思想和方法的工具箱。 ##### [What is geometry?](https://quivergeometry.net/#what_is_geometry) From an abstract point of view, we may ask what geometry is fundamentally *about*. One appealing answer is that it is the ***logic of movement***: the rules by which an object or agent may be moved from place to place, or a more abstract system may transition from state to state, and the rules used to reason about these transitions. There are only two fundamental ingredients: the ***states / places*** that an agent or system can be in, and the ***movements / transitions*** available at each such state or place. 从抽象的角度来看,我们可能会问几何学的本质是什么。一个吸引人的答案是它是运动的逻辑:对象或代理可以从一个地方移动到另一个地方的规则,或者一个更抽象的系统可以从一个状态转换到另一个状态,以及用于推理这些转换的规则。只有两个基本要素:**代理或系统可以处于的状态/位置,以及在每个这样的状态或位置可用的运动/转换。** Both of these ingredients are discrete, taking only a finite number of value in any given instantiation: an agent may move from state $x$ to $y$ to $z$, but it does so in discrete jumps, and describes these with discrete labels:  Time, if it is involved in such descriptions, is also discrete, passing like the ticking of a CPU clock. When such a discrete theory of geometry makes contact with the continuous objects of classical geometry, it should do so on its own terms, and continuous objects will be seen as the limiting case of particular discrete geometries. That is to say, we should *not* try to reach discrete geometry by starting from continuous geometry, since that would get it backward. We should **"commit to the bit**" from the beginning. 当这种离散几何理论与经典几何的连续对象接触时,它应该按照自己的方式进行,而连续对象将被视为特定离散几何的极限情况。也就是说,我们不应该试图通过从连续几何开始来达到离散几何,因为那样会使它倒退。我们应该从一开始就“致力于一点”。 ##### [Discrete physics](https://quivergeometry.net/#discrete_physics) It is my belief that the universe will turn out to be operating on fundamentally discrete, computational principles. If this becomes accepted scientific wisdom, we will in retrospect see continuous geometry as an *enticing and useful illusion*, but one that never had the physical basis that was its historical justification and inspiration. An ancillary belief is that many of the rich phenomena that play out in continuous geometry will have fascinating discrete counterparts – and that these will prove very fruitful to study as a kind of digital reinterpretation of the canon of traditional mathematics. Hopefully it will not prove grandiose to imagine that discrete geometry along the lines described here is the logical place to start if we wish to reimagine mathematics from an honestly computational perspective. 我相信,宇宙将被证明是在基本的离散的、计算性的原理上运行。如果这成为公认的科学智慧,我们回过头来会看到连续几何是一个吸引人和有用的幻象,但它从来没有作为其历史理由和灵感的物理基础。 一个附带的信念是,许多在连续几何中出现的丰富现象将有迷人的离散对应物--而且这些将被证明是非常富有成效的研究,是对传统数学教规的一种数字重新解释。如果我们希望从诚实的计算角度来重新想象数学,那么按照这里所描述的思路来想象离散几何学是一个合乎逻辑的起点,希望这不会被证明是夸张的。 ##### [Graphs and quivers](https://quivergeometry.net/qg/graphs-and-quivers/#graphs_and_quivers) We started with the intuition that geometry should be about states/places: $x, y,z $ and their transitions. Evidently we have the main ingredients of a **graph**, specifically a **directed graph**:  It turns out that we will have to consider specific kinds of directed graphs if we wish to build a notion of geometry. These graphs are quivers, also known as directed multigraphs, which are directed graphs that allow multiple edges, and cycles, between any pair of vertices:  ##### [Cardinal quivers](https://quivergeometry.net/qg/graphs-and-quivers/#cardinal_quivers) A seemingly fundamental geometrical idea is that of a direction. For discrete geometry, a direction will take the form of a label for an entire set of transitions: these are the transitions that, although they are between different pairs of vertices, are all in the same direction (in whatever sense). We’ll call this label a cardinal, by analogy with the cardinals of a compass **{N,E,S,W}**. We'll write cardinals in a typewriter or sans-serif font to distinguish them from symbols representing vertices, etc. A cardinal quiver is a quiver with a set of (typically repeated) labels on the edges of the quiver, called cardinals, with the property of local uniqueness: **the list of cardinals on edges {entering, leaving} a given vertex cannot contain duplicates** 一个看似基本的几何学概念是方向。 对于离散几何,方向将采用整个过渡集的标签形式:这些过渡虽然位于不同的顶点对之间,但都在同一方向上(无论在何种意义上)。我们将这个标签称为基数,类似于指南针 **{N,E,S,W}** 的基数。我们将用打字机或 sans-serif 字体书写基数,以将它们与表示顶点的符号等区分开来。 基数quiver是在quiver边缘带有一组(通常是重复的)标签的quiver,称为基数,具有局部唯一性: **边上的基数列表 {entering, leave} 给定顶点不能包含重复项**。 We’ll only discuss cardinal quivers from now on, so I’ll just call refer to them from now on as quivers. If we need to refer to the classical notion of a quiver as a directed multigraph, we’ll use the term unlabelled quiver. Since cardinals will almost always label multiple edges in a quiver, we will use color to represent the edges labeled by each cardinal, and choose cardinal letters e.g. $r, g, b$ to reflect these colors: 由于基数几乎总是在quiver中标记多条边,我们将使用颜色来表示每个基数标记的边,并选择基数字母,例如$r, g, b$ 来反映这些颜色:  Here are more examples – since the arrowhead color indicates the name of the cardinal, we'll drop the legends. The cardinals label multiple edges, but still obey local uniqueness:  Note that the right-most example has some of the intuitive aspects of an actual discrete geometry: the cardinal r can be taken (meaning a move in the direction **r** can be made) for any of the states $x, y, z$. Taking **r** repeatedly simply cycles through these states: **a discrete analog of a circle.** ### The Hard Problem of Consciousness Has an Easy Part We Can Solve origin: [The Hard Problem of Consciousness Has an Easy Part We Can Solve](https://nautil.us/blog/the-hard-problem-of-consciousness-has-an-easy-part-we-can-solve) **H**ow does consciousness arise? What might its relationship to matter be? And why are some things conscious while others apparently aren’t? These sorts of questions, taken together, make up what’s called the “hard problem” of consciousness, coined some years ago by the philosopher [David Chalmers](https://nautil.us/blog/heres-how-well-know-an-ai-is-conscious). There is no widely accepted solutionsolución to this. But, fortunately, we can break the problemel problema down: If we can tackle what you might call the easy part of the hard problem, then we might make some progress in solving the remaining hard part. > Consciousness is a snapshot of time. In a 2019 paper published in Frontiers in Human Neuroscience, we laid out our General Resonance Theory of consciousness, a framework with a **panpsychist** foundation that may, at least in theory, provide more complete answers to the full array of questions the hard problem of consciousness poses. The easy part of the hard problem is the “combination problem,” also known as the “boundary problem.” It’s a challenge not only for panpsychist approaches to consciousness, but also materialist approaches: How do parts, like neurons, combine into a whole, a single consciousness? For panpsychists, the question gets more precise: How do micro-conscious entities (whatever they are) combine into macro-conscious entities, like human or cat consciousness? 在2019年发表在《人类神经科学前沿》(Frontiers in Human Neuroscience)上的一篇论文中,我们阐述了我们关于意识的一般共振理论,这是一个具有泛心理主义基础的框架,至少在理论上可能为意识这个硬问题所带来的全部问题提供更完整的答案。硬问题的简单部分是 "组合问题",也被称为 "边界问题"。这不仅是对泛心理主义意识方法的挑战,也是对唯物主义方法的挑战。各个部分,比如神经元,如何结合成一个整体,一个单一的意识?对于泛心理学家来说,这个问题变得更加精确:微观意识实体(无论它们是什么)如何结合成宏观意识实体,比如人类或猫的意识? Our answer, in short, is this: **Things that resonate in proximity to each other will, under certain conditions, achieve a shared physical resonance, and thereby a combined consciousness.** This shared resonance refers to frequencies, or cycles per second. And it’s looking more and more likely, as data comes in, that the key frequencies at issue for human and other animal consciousness is electromagnetic field resonance of various types. This is measured by tools like electroencephalography and magnetoencephalography. By achieving a shared resonance, the bandwidth and speed of information flows increase remarkably, allowing far more energy and information to flow between the constituents. This will, all else equal, result in a new higher-level consciousness. Where before there was a lack of resonance and rather chaotic energy and information flows, now there is a smooth transfer of energy and information. We call this “the shared resonance conjecture” in our theory. 我们的答案,简而言之,就是这样。**彼此接近的事物在一定条件下,会实现共同的物理共振,从而形成联合意识。**这种共同的共振指的是频率,或每秒的周期。而随着数据的出现,看起来越来越有可能,人类和其他动物意识的关键频率是各种类型的电磁场共振。这可以通过脑电图和脑磁图等工具来测量。通过实现共同的共振,信息流的带宽和速度明显增加,允许更多的能量和信息在成分之间流动。在其他条件相同的情况下,这将导致一个新的更高层次的意识。以前缺乏共振,能量和信息流动相当混乱,现在则是能量和信息的顺利转移。在我们的理论中,我们把这称为 "共享共振猜想"。 For us, this combination of consciousness, through shared resonance, does not squelch the consciousness of smaller conscious entities—they continue as parts of the new larger whole. “The many become one and are increased by one,” as Whitehead put it succinctly in his work. 对我们来说,这种意识的结合,通过共享共振,并没有压制较小的意识实体的意识--它们继续作为新的较大整体的一部分。正如怀特海在他的作品中简明扼要地指出的那样,"许多人变成了一个,并被一个所增加"。 In the context of neural information flows, **the specific shared resonance is known as neural synchrony.** This kind of synchrony is a well-established phenomenon key for brain processes and human consciousness. Neural firing patterns and electromagnetic field phenomena more generally can achieve synchrony across distant parts of the brain and, thereby, form a larger and more complex consciousness—which leads to our second conjecture: the “boundary conjecture.” This states that the boundaries of a consciousness like ours depends on the velocity and frequency of the resonance chains connecting its parts. 在神经信息流的背景下,特定的共享共鸣被称为神经同步。这种同步性是大脑过程和人类意识的一个公认的关键现象。神经发射模式和更普遍的电磁场现象可以在大脑的遥远部分实现同步,从而形成一个更大和更复杂的意识--这导致了我们的第二个猜想:"边界猜想"。这说明,像我们这样的意识的边界取决于连接其各部分的共振链的速度和频率。 What do boundaries even mean in the context of a seemingly immaterial thing like consciousness? What we’re referring to is the boundary of the physical energy and information flows that provide the content of consciousness. It’s something like axiomatic that for any information (like perceptions or internally-generated thoughts) to become part of consciousness, in each moment that information needs to reach the physical geography generating that consciousness. This would be the brain, in the case of humans and other animals (though not exclusively the brain, as we’re learning). 在意识这样一个看似非物质的东西的背景下,边界到底是什么意思?我们所指的是提供意识内容的物理能量和信息流的边界。对于任何信息(如感知或内部产生的想法)成为意识的一部分,在每个时刻,信息需要到达产生该意识的物理地理环境,这就像公理一样。就人类和其他动物而言,这将是大脑(虽然不完全是大脑,因为我们正在学习)。 If, for example, a gunshot is fired in Mississippi at 12 noon, the sound of that gunshot is not going to be part of the consciousness of a person on the top of Mount Everest only a minute later. That information simply can’t reach our person on Everest in that timeframe. Velocity matters. And bandwidth matters for similar reasons: If there’s not a big enough information highway, then some information may not make it. Consciousness in each moment is a function of the information that reaches us. But that’s only half of it. It’s also a function of the processing of that information. 例如,如果中午12点在密西西比州开了一枪,那枪声就不会成为一分钟后在珠穆朗玛峰顶上的人的意识的一部分。在那个时间范围内,这些信息根本无法到达我们在珠穆朗玛峰上的人。速度很重要。出于类似的原因,带宽也很重要。如果没有足够大的信息高速公路,那么一些信息可能无法到达。每个时刻的意识是到达我们的信息的一个功能。但这只是它的一半。它也是对这些信息进行处理的一个功能。 For example, visual information from the retina is highly processed by the retina and the brain before it becomes visual perception in our consciousness. Light falls on the retina, goes through various layers of neurons, is sent down the optic nerve across the brain, and then all the way to the back of the brain where the visual cortex resides. It’s then processed further by visual cortex and then, somehow (we still don’t know the full details) that information becomes visual imagery that includes colors, lines, shadows, along with the affect that accompanies our visual perception, such as the pleasure of beholding a beautiful work of art, say. 例如,来自视网膜的视觉信息在成为我们意识中的视觉感知之前,已经被视网膜和大脑高度处理。光线落在视网膜上,经过各层神经元,沿着视神经穿过大脑,然后一直到大脑后面的视觉皮层。然后由视觉皮层进一步处理,然后,以某种方式(我们仍然不知道全部细节),这些信息成为视觉图像,包括颜色、线条、阴影,以及伴随我们的视觉感知的影响,例如,看到一件美丽的艺术品的快乐。 ### GO编程模式 : 泛型编程 origin: [GO编程模式 : 泛型编程](https://coolshell.cn/articles/21615.html) ```go package main import "fmt" func print[T any] (arr []T) { for _, v := range arr { fmt.Print(v) fmt.Print(" ") } fmt.Println("") } func main() { strs := []string{"Hello", "World", "Generics"} decs := []float64{3.14, 1.14, 1.618, 2.718 } nums := []int{2,4,6,8} print(strs) print(decs) print(nums) } ``` 上面这个例子中,有一个 `print()` 函数,这个函数就是想输出数组的值,如果没有泛型的话,这个函数需要写出 `int` 版,`float`版,`string` 版,以及我们的自定义类型(`struct`)的版本。现在好了,有了泛型的支持后,我们可以使用 `[T any]` 这样的方式来声明一个泛型类型(有点像C++的 `typename T`),然后面都使用 `T` 来声明变量就好。 上面这个示例中,我们泛型的 `print()` 支持了三种类型的适配—— `int`型,`float64`型,和 `string`型。要让这段程序跑起来需要在编译行上加上 `-gcflags=-G=3`编译参数(这个编译参数会在1.18版上成为默认参数),如下所示: ```bash $ go run -gcflags=-G=3 ./main.go ``` 有了个操作以后,我们就可以写一些标准的算法了,比如,一个查找的算法 ```go func find[T comparable] (arr []T, elem T) int { for i, v := range arr { if v == elem { return i } } return -1 } ``` 我们注意到,我们没有使用 `[T any]`的形式,而是使用 `[T comparable]`的形式,`comparable`是一个接口类型,其约束了我们的类型需要支持 `==` 的操作, 不然就会有类型不对的编译错误。上面的这个 `find()` 函数同样可以使用于 `int`, `float64`或是`string`类型。 从上面的这两个小程序来看,Go语言的泛型已基本可用了,只不过,还有三个问题: - 一个是 `fmt.Printf()`中的泛型类型是 `%v` 还不够好,不能像c++ `iostream`重载 `>>` 来获得程序自定义的输出。 - 另外一个是,go不支持操作符重载,所以,你也很难在泛型算法中使用“泛型操作符”如:`==` 等 - 最后一个是,上面的 `find()` 算法依赖于“数组”,对于hash-table、tree、graph、link等数据结构还要重写。也就是说,没有一个像C++ STL那样的一个泛型迭代器(这其中的一部分工作当然也需要通过重载操作符(如:`++` 来实现) ##### Stack 栈 编程支持泛型最大的优势就是可以实现类型无关的数据结构了。下面,我们用Slices这个结构体来实现一个Stack的数结构。 首先,我们可以定义一个泛型的Stack ```go type stack [T any] []T ``` 看上去很简单,还是 `[T any]` ,然后 `[]T` 就是一个数组,接下来就是实现这个数据结构的各种方法了。下面的代码实现了 `push()` ,`pop()`,`top()`,`len()`,`print()`这几个方法,这几个方法和 C++的STL中的 Stack很类似。(注:目前Go的泛型函数不支持 export,所以只能使用第一个字符是小写的函数名) ```go func (s *stack[T]) push(elem T) { *s = append(*s, elem) } func (s *stack[T]) pop() { if len(*s) > 0 { *s = (*s)[:len(*s)-1] } } func (s *stack[T]) top() *T{ if len(*s) > 0 { return &(*s)[len(*s)-1] } return nil } func (s *stack[T]) len() int{ return len(*s) } func (s *stack[T]) print() { for _, elem := range *s { fmt.Print(elem) fmt.Print(" ") } fmt.Println("") } ``` ##### LinkList 双向链表 下面我们再来看一个双向链表的实现。下面这个实现中实现了 这几个方法: - `add()` – 从头插入一个数据结点 - `push()` – 从尾插入一个数据结点 - `del()` – 删除一个结点(因为需要比较,所以使用了 `compareable` 的泛型) - `print()` – 从头遍历一个链表,并输出值。 ```go type node[T comparable] struct { data T prev *node[T] next *node[T] } type list[T comparable] struct { head, tail *node[T] len int } func (l *list[T]) isEmpty() bool { return l.head == nil && l.tail == nil } func (l *list[T]) add(data T) { n := &node[T] { data : data, prev : nil, next : l.head, } if l.isEmpty() { l.head = n l.tail = n } l.head.prev = n l.head = n } func (l *list[T]) push(data T) { n := &node[T] { data : data, prev : l.tail, next : nil, } if l.isEmpty() { l.head = n l.tail = n } l.tail.next = n l.tail = n } func (l *list[T]) del(data T) { for p := l.head; p != nil; p = p.next { if data == p.data { if p == l.head { l.head = p.next } if p == l.tail { l.tail = p.prev } if p.prev != nil { p.prev.next = p.next } if p.next != nil { p.next.prev = p.prev } return } } } func (l *list[T]) print() { if l.isEmpty() { fmt.Println("the link list is empty.") return } for p := l.head; p != nil; p = p.next { fmt.Printf("[%v] -> ", p.data) } fmt.Println("nil") } ``` 上面这个代码都是一些比较常规的链表操作,学过链表数据结构的同学应该都不陌生,使用的代码也不难,如下所示,都很简单,看代码就好了。 ```go func main(){ var l = list[int]{} l.add(1) l.add(2) l.push(3) l.push(4) l.add(5) l.print() //[5] -> [2] -> [1] -> [3] -> [4] -> nil l.del(5) l.del(1) l.del(4) l.print() //[2] -> [3] -> nil } ``` ##### Map-Reduce是的业务语义  通过上面的一些示例,你可能有一些明白,Map/Reduce/Filter只是一种控制逻辑,真正的业务逻辑是在传给他们的数据和那个函数来定义的。是的,这是一个很经典的“业务逻辑”和“控制逻辑”分离解耦的编程模式。下面我们来看一个有业务意义的代码,来让大家强化理解一下什么叫“控制逻辑”与业务逻辑分离。 ##### 泛型 Reduce 接下来,我们再来看一下我们的Reduce函数,reduce函数是把一堆数据合成一个。 ```go func gReduce[T1 any, T2 any] (arr []T1, init T2, f func(T2, T1) T2) T2 { result := init for _, elem := range arr { result = f(result, elem) } return result } ``` 函数实现起来很简单,但是感觉不是很优雅。 - 也是有两个类型 `T1` 和 `T2`,前者是输出数据的类型,后者是佃出数据的类型。 - 因为要合成一个数据,所以需要有这个数据的初始值 `init`,是 `T2` 类型 - 而自定义函数 `func(T2, T1) T2`,会把这个init值传给用户,然后用户处理完后再返回出来。 下面是一个使用上的示例——求一个数组的和 ```go nums := []int {0,1,2,3,4,5,6,7,8,9}sum := gReduce(nums, 0, func (result, elem int) int { return result + elem})fmt.Printf("Sum = %d \n", sum) ``` ##### 泛型 filter filter函数主要是用来做过滤的,把数据中一些符合条件(filter in)或是不符合条件(filter out)的数据过滤出来,下面是相关的代码示例 ```go func gFilter[T any] (arr []T, in bool, f func(T) bool) []T { result := []T{} for _, elem := range arr { choose := f(elem) if (in && choose) || (!in && !choose) { result = append(result, elem) } } return result}func gFilterIn[T any] (arr []T, f func(T) bool) []T { return gFilter(arr, true, f)}func gFilterOut[T any] (arr []T, f func(T) bool) []T { return gFilter(arr, false, f)} ``` 其中,用户需要提从一个 `bool` 的函数,我们会把数据传给用户,然后用户只需要告诉我行还是不行,于是我们就会返回一个过滤好的数组给用户。 比如,我们想把数组中所有的奇数过滤出来 ```go nums := []int {0,1,2,3,4,5,6,7,8,9}odds := gFilterIn(nums, func (elem int) bool { return elem % 2 == 1})print(odds) ``` ### Misc - [v2ex](https://www.v2ex.com/t/801337#reply13)| Java 强大的是 JSR 那套社区规范,规范成就生态,尽量避免重复造轮子,即使重复造的轮子共用一套规范也能无缝切换。 - [v2ex](https://www.v2ex.com/t/801448#reply7) | token vs session - Cookie:在浏览器的 CookieJar 中存储信息,比如购物车等,每次 HTTP 请求强制携带; - Session:通过存储在 CookieJar 中的小段信息作为 Token,在服务器中加载相关完整信息; - Token:通过存储在浏览器 localStorage 中加密签名过的 Token (一般是 JWT ),在 HTTP Authorization Header 中可选发送,并在服务器汇总加载相关完整信息。 token 可以节约后端的兼容时间,用 token 代替 session 可以做到 网页、app 、微信公众号等公用一套接口即可。 token 看项目,大部分项目就是简单的把 token 当成 session 的另版,少部分是把 token 当做信息传输 - [v2ex](https://www.v2ex.com/t/801308#reply4) | 用节流做防抖合适么 - 没记错的话, lodash 里的 debounce 和 throttle 底层是同样的方法. - 用户提交:promise 期间加一个 disable 就可以了,觉得不应该放到防抖节流里面 - 在密集触发的情况下,防抖 debounce 时中间不会调用,只在最后一次触发后延时调用,节流 throttle 是中间每隔固定间隔会调用。两者都可以选择 trailing,所以节流拿到的窗口尺寸也不会有问题。 个人觉得更好的例子是 **input onchange** 时往后端发请求,防抖就很合适,用户密集输入时不需要请求,等用户停顿下来后再请求。至于 resize,看项目要求,需不需要在用户密集 resize 期间(拉来拉去时)获取窗口尺寸,如果需要,就用节流,如果只需要在用户停顿的时候再获取窗口尺寸,就可以用防抖了 - [zhihu](https://www.zhihu.com/question/288532111/answer/461965376) | 能制造二向箔(dual vector foil)的文明,一定对空间理论,弦论,拥有非常深刻的认知。并拥有非常成熟的空间操纵技术,才能造出二向箔。 - 卡尔达肖夫指数(Kardashev Scale) - [HX](https://news.ycombinator.com/item?id=28467397) | Interesting that "**broken access controls**" made it into the top spot.What happens is that often the providers offer good support for role-based access control but developers just plain ignore it and e.g. include tokens with global read permissions into the app code, or do not properly restrict the permissions of individual tokens, making it possible to e.g. read the whole database with a normal user token. 