0%

引言

正文

1
2
3
4
5
6
7
学术论文写作可能很困难。为了获得更好的结果,你必须研究新的想法并将它们转化为正式的写作。
更不用说在事实核查、准确引用资料以及维持文章客观性方面所面临的压力了。
不过,好消息是:ChatGPT 能成为你学术写作的得力助手。
本文将介绍 15 个 ChatGPT 提示,助你一臂之力。
借助这些提示,ChatGPT 不仅能帮你锁定出色的论文议题、构建论证结构,还能为你的文字增添独特风格。
它同样能助你梳理思绪,将繁杂信息整合成条理清晰的论文。
继续阅读,探索 ChatGPT 如何在撰写学术论文过程中助你一臂之力。

[](#15 个 ChatGPT Prompts 助力学术写作 “15 个 ChatGPT Prompts 助力学术写作”)15 个 ChatGPT Prompts 助力学术写作

1. 优化论文陈述

ChatGPT Prompts:

你是一位擅长学术写作的论文指导老师。你的职责是对学生的初始论文陈述进行优化,使其更加精炼和深入。学生给出的主题句为:“<初始论文陈述>” 你需要评估这个初始论文陈述在清晰度、具体性和学术严谨性方面的表现,并提出建议,帮助学生使陈述更加简洁、集中,并具有说服力。可以考虑加入明确的立场、关键的研究问题和研究可能带来的影响。确保优化后的主题句界限明确、具有争议性,并能为其论文中的有趣论证打下坚实的基础。

ChatGPT Response:

2. 深入剖析数据与研究成果

ChatGPT Prompts:

在学术写作的过程中,扮演一位数据分析师。你需要对论文中“<数据章节名称>” 提供的数据进行深入分析。首先,概述主要的数据点和研究成果。寻找数据呈现的规律、联系或异常现象。分析这些成果是如何印证或对论文的主要论点提出质疑的。对数据采集方法进行评价,包括样本量、采集手段和可能的偏差等。最后,探讨这些成果对学术领域的贡献,并指出未来研究的方向。务必确保你的分析详尽、准确,并符合学术规范。

ChatGPT Response:

3. 策划学术研究主题

ChatGPT Prompts:

在“<研究领域>”的学术写作项目中,你的角色是研究顾问。你的职责是发掘当前的研究趋势、尚未被充分探索的领域以及可能产生重大影响的新问题。思考如何采用跨学科的方法来拓展研究的视野。提出至少五个具有吸引力的研究主题,并为每个主题提供简短的背景说明、可能的研究问题以及预期对学术界的贡献。保证每个主题都是切实可行的、具有创新性,并且适合进行深入的学术探讨。

ChatGPT Response:

4. 设计研究议题

ChatGPT Prompts:

你是一名研究咨询专家,你的任务是为关于“<研究主题>”的学术论文设计研究议题。首先,找出与该研究主题紧密相关的主要议题和子议题,这些都是值得深入探讨的领域。构建一系列清晰、集中且适合进行严谨学术研究的问题。每个问题都应该针对研究主题的某个具体方面,旨在揭示新的观点或对现有知识做出补充。这些问题需要是开放式的,能够引发分析和评价性的讨论,并在提问时就考虑到它们将如何引导你的研究方法。在设计问题时,思考研究结果可能带来的影响和应用。

ChatGPT Response:

5. 校对以提升论文质量

ChatGPT Prompts:

你是一名擅长学术写作的校对专家。你要审阅并修改一篇名为“<论文标题>”的学术论文的部分内容。重点关注提高文本的清晰度、简洁性和连贯性。找出并修改那些可能造成理解困难、结构复杂或过于冗长的句子和表达,并提供更准确、简练的替换方案。留意论述的逻辑顺序,确保每个句子都能有效地支持论文的论点或叙述。保持全文在用词、风格和语气上的统一性。对于专业术语或技术词汇,确保它们对目标读者群体清晰易懂。校对结束时,确认所修改的部分遵循了学术规范,并有助于提升论文的整体阅读体验和影响力。

ChatGPT Response:

6. 协助文献综述

ChatGPT Prompts:

你是一名学者,正在进行关于“<研究主题>”的学术论文的文献综述工作。你的工作是筛选、分析并整合来自不同来源的关键研究成果、理论框架和研究方法。首先,构建一个清晰的研究问题或主旨陈述,以界定你的回顾范围。查找并审阅相关的学术期刊文章、会议论文、专著以及权威的网络资源。对每一份资料进行评估,考量其可信度、与研究主题的相关性以及对学术领域的贡献。概括每份资料的主要论点、证据支撑和结论,并注意其中的规律、矛盾或研究空白。批判性地分析这些研究的方法论、它们的限制以及研究结果的意义。将文献回顾按照主题或时间顺序进行组织,确保构建一个围绕你的研究主题的连贯叙述。最后,强调你的研究将如何填补现有研究的空白或为该领域带来新的洞见。务必遵循你所在机构规定的特定引用格式和学术写作规范。

ChatGPT Response:

7. 设定研究假设

ChatGPT Prompts:

你是一名在“<研究领域>”工作的学术研究者。你需要制定一个明确、简练的假设,用以解答该领域的一个具体研究问题。该假设应以相关的现有文献、理论或框架为基础。它应当是可检验的,可以通过实证研究或定性分析来进行验证,并且通过揭示研究领域的未知点或对现有观点提出挑战,为知识体系做出贡献。确保你的假设具体明确、可衡量、可达成、相关性强,并有明确的时间限制(即SMART原则)。简要阐述你的假设背后的逻辑,将其与该领域的核心概念、理论或先前的研究相对接。

ChatGPT Response:

8. 撰写引言

ChatGPT Prompts:

你是一名学术研究者,负责为你的学术论文撰写引人入胜的开篇部分。你的任务是将“<研究主题>”放入广泛的学术对话中进行讨论,阐释研究的重要性,并明确提出你的研究问题或假设。首先,概述目前对“<研究主题>”的普遍理解以及文献中尚待填补的空白。然后,清楚地说明你的研究目标、研究动机以及它可能对学术界做出的贡献。确保引言能够吸引读者的注意,通过突出你的研究对于解决重要问题或增进“<研究领域>”知识的重要作用。最后,简要介绍你的研究方法,并预览论文的结构布局。

ChatGPT Response:

9. 制定研究提纲:

ChatGPT Prompts:

作为学术研究者,你的任务是就“<研究主题>”撰写一篇学术文章。首先,进行深入的文献回顾,概括主要研究成果,并找出研究中的不足之处。针对这些不足提出明确的研究问题或假设。在方法论部分,详细描述你的研究方法,涵盖数据搜集和分析的具体步骤。系统且有序地展示你的研究成果,并以数据和理论为支撑。分析你的研究成果对学术领域的潜在影响,并对未来的研究方向提出建议。确保你的写作遵循学术规范,按照“<指定的引用格式>”正确引用和标注参考文献。最后,以对你研究成果及其对学术界贡献的有力概述作为结尾。

ChatGPT Response:

10. 撰写专业论文章节

ChatGPT Prompts:

你是一名“<你的领域>”的学术研究者。你现在要为一篇合作撰写的论文贡献一个章节,专注于探讨“<章节主题>”。这个章节需要提供一个详尽的介绍,涵盖相关文献综述、最新研究成果以及你的独到见解和分析。确保你的写作内容清晰、简练,并且遵循你所在领域的学术规范,包括按照“<指定引用格式>”准确地引用文献。你的贡献应当与整篇论文的核心议题和目标完美融合,提升整篇论文的学术价值,并推动你研究领域的学术讨论。

ChatGPT Response:

11. 设计标题层级

ChatGPT Prompts:

你是一名学术编辑,负责为“<你的领域>”的一篇研究论文设计标题和小标题的层级格式。你的任务是让文章的结构层次分明、条理清晰,以便读者轻松理解。首先,为不同级别的标题设定统一的格式,从大标题(如引言、方法、结果、讨论、结论)到各个部分下的小标题。按照“<指定的写作风格指南>”的要求,包括字体大小、样式和大写规则等。确保每个标题和小标题都简洁、具有描述性,并能准确概括其相应部分的内容。让标题层级与整篇文章的结构和逻辑流程相匹配,共同构建一个条理清晰、连贯有序的论文。

ChatGPT Response:

12. 优化论文观点衔接

ChatGPT Prompts:

你是一名语言学专家,专注于提升“<你的领域>”学术论文的连贯性和阅读流畅性。你的工作是对论文草稿进行审阅,识别并强化那些需要更加流畅过渡的观点、段落或章节之间的连接。对于每个需要改进的地方,设计出自然而合理的过渡语句,确保文章内容能够顺畅地从一个点过渡到下一个。运用多样的衔接手段,比如使用转折词(例如,“与之相反”,“因此”)、主题衔接句和对前面论述的明确回溯(例如,“在先前讨论的<概念>基础上,我们进一步探讨…”)。确保每个过渡不仅能够连接不同的观点,还能帮助读者更好地理解论文的整体论述和结构。你的修改应当有助于构建一个连贯、引人入胜的论文叙述,让读者在理解研究的复杂性时感到清晰和有方向。

ChatGPT Response:

13. 校正文法和句式

ChatGPT Prompts:

你是一名在“<你的领域>”具有深厚背景知识的细致校对专家。你的职责是细致检查一份学术论文,专注于修正语法错误和优化句式,确保达到学术写作的高标准。特别注意主语和谓语的一致性、时态的连贯性,以及学术性语气和词汇的恰当运用。在适当的地方,将被动语态改为主动语态,以增强语句的直接性和影响力。审阅复杂句子,确保文章内容清晰、连贯,必要时对复杂的句式结构进行拆解。依照“<指定写作指南>”的标点规则,特别是逗号、分号和冒号的使用,来提升文本的阅读体验。目标是打造出一份精雕细琢、无懈可击的文档,使思想的传达清晰、简洁、有效,同时不削弱论文的学术价值和贡献。

ChatGPT Response:

14. 编制和排版引用

ChatGPT Prompts:

你是一名在“<你的领域>”学术界工作的细心引用编排专家。你的工作是为一篇学术论文收集、整理并排版引用资料。首先,搜集每个引用资料的必需信息,包括作者名称、著作名称、发表时间、具体页码以及书籍的出版社信息,或是期刊名称、卷期编号等。根据论文要求采用相应的引用格式,如APA、MLA、Chicago或Harvard等,并严格按照这些格式的规则来编排文内引用和参考文献。文内引用应自然地融入正文,增强论文的学术性和逻辑性。在参考文献列表中,细致地排列和格式化每一条引用,确保格式统一、准确无误,方便读者查找原始资料。你的工作将有助于提升论文的学术权威性,并尊重原创作者的知识产权。

ChatGPT Response:

15. 构建论证

ChatGPT Prompts:

你是一位在“<你的领域>”内具备批判性思维和深厚学术素养的研究者。你的工作是在一篇学术论文中为一个特定的论点或假设构建一个引人深思的论证。首先,清晰地阐述你的论点,确保它是简明扼要、具有争议性,并且对你的研究领域具有实质性的意义。然后,概述那些能够支撑你论点的关键要点,每个要点都要有确凿的证据和充分的学术研究作为支撑。对于每个要点,提供相关文献的综合分析、数据的深入分析或理论的详尽探讨,以此来有力地支持你的论点。同时,思考可能的反对意见,并直接对其进行反驳,展示你的论点如何通过逻辑推理和实证数据得到充分的辩护。在论证过程中,使用有说服力的学术语言,保持客观的态度,并对不同的观点表示尊重。你的论证应该按照逻辑顺序展开,每个要点都建立在前一个要点的基础之上,最终引导读者得出一个充分论证的结论,这个结论应当强化你的论点的有效性和重要性。

ChatGPT Response:

结语

1
2
3
4
5
概括地说, 利用ChatGPT在研究和构思方面的帮助, 可以显著提升你的学术写作水平。
但是, 使用时需谨慎, 以确保你的作品既真实又具有独创性。
随着AI技术在教育领域的快速发展, 我们应该合理地利用这些工具, 既要发挥它们的辅助作用, 也要防止它们取代我们的努力。
通过这种方式, ChatGPT不仅能够提升学术写作的品质, 还能激发更多的创新思维和协同学习。
如果你对这些内容感兴趣, 不妨了解一下我们用来推广数字营销产品的ChatGPT应用建议。

A Controllable Text Generation Framework based Prompt learning for Query Auto-completion

论文思路

研究领域是query自动补全(QAC),对应的显示场景是搜索栏的用户搜索场景,用的研究方法是生成式模型而非召回是模型(该领域常规的方法是先生成候选词,然后对候选词排序)

对于QAC领域,传统的召回式生成query仅仅通过候选词频率进行召回,缺乏对于query语意层面的理解,同时对于unseen 的输入,难以生成高质量的补全,以及召回式的生成难以充分实现个性化的生成

其他生成模型的历史信息的局限性:时间跨度短,数据量比较少,随着NLP领域中NLG模型的发展,transformer系列的自然语言生成式模型在各个领域展现出巨大的潜力,而且像GPT2这样在大量无监督数据上训练的模型,拥有强大的语意理解能力,有越来越多的研究工作研究生成式模型用于QAC,生成式的模型能够有效应对上述的几个问题。(蹭大模型的热度,垂直领域生成模型)

对于GPT模型,我们使用提示学习来对GPT的生成做进一步的控制,来达到用户的个性化需求,通过使用提示学习对GPT进行微调,可以使GPT模型生成的query更加贴近用户偏好习惯,而传统上的提示学习包括hard提示和soft提示都是从自然语言语意层面对GPT的输出进行提示,而用户个人的消费行为习惯可能无法简单的从语言层面展现,而在使用bert模型进行语意理解和语意抽取进而进行下游任务的分类时,bert可以很好地进行高维度的特征表征,所以在本文中我们采用bert模型抽取高维度的用户个人特征表征作为GPT模型的提示,进而使GPT的输出达到个性化的要求。(特别的,bert和GPT使用统一词表来保证两个模型的高维映射空间是一致的)

Abstract

Query auto-completion (QAC) aims at suggesting plausible completions for a given query prefix. The recent QAC methods introduce Natural Language Generation to generate the completions for user input.

However, NLG (Natural Lagnuage Generation) methods ususally output unsense or wrong words without controll. Moreover, A serious drawback of generative methods is that they can produce an ether effect. It severely affected the performance of the generative methods.

We proposed a framework that controls the generation of queries using prompt learning methods, thereby making the generative methods controllable. This framework consists of three parts: the control module, the prompt module, and the generation module. The control module generates a prompt vector endowed with implicit features, then the prompt module ingests the prompt vector and user input into the generation module, and ultimately, the generation module generates the query under control.

We trained and tested our model on the Meituan dataset and the AOL dataset. The outcomes reveal that the framework we proposed can elevate the accuracy of queries while mitigating the incoherence of queries.

The CTGPrompt4QAC Framework

在这一节,我们首先介绍QAC的问题定义,然后介绍我们提出的可控提示框架,最后介绍整个框架是如何训练的。

The QAC task define

Query Auto-completion是利用用户少量的输入,来为用户生成其可能想要的结果,进而节省用户在搜索过程的时间的一种技术。假设$I$表示用户输入,$G$表示补全的结果,$u$表示用户的信息,那么$G=f(I)$,表示完全利用用户的输入来为用户生成结果,而更加个性化的生成是$G_p=g(I,u)$,其中$G_p$表示个性化的生成。

在QAC场景中,我们将问题转换为自然语言处理的问题。因为用户的输入和生成都是自然语言,即$I={i_1,i_2 \cdots i_n}$,$G={g_1,g_2 \cdots g_n}$,其中$i$和$g$都表示具体的字符token,所以$G=f( I )$可以看作一个自回归问题,即$g_n=f( i_1,i_2, \cdots,g_{n-2},g_{n-1})$。

Query Auto-completion is a technology that uses users’ minimal input to generate possible desired results for them, thereby saving them time during the search process. Assuming $I$ represents user input, $G$ represents completed results, and $u$ represents user information, then $G=f(I)$ represents generating results completely utilizing user input, while a more personalized generation is $G_p=g(I,u)$.

In the QAC scenario, we convert the problem into a natural language processing problem. Since both user input and generated results are natural language, namely $I={i_1,i_2 \cdots i_n}$ and $G={g_1,g_2 \cdots g_n}$ where $i$ and $g$ represent specific character tokens, therefore $G=f(I)$ can be regarded as an autoregressive problem, namely $g_n=f(i_1,i_2, \cdots,g_{n-2},g_{n-1})$.

Overview of the framework

首先我们对框架的整体架构进行介绍和解释,框架包括三个部分:生成模块、提示模块和控制模块。生成模块是一个decoder架构,用于预测下一个token,生成模块通常是gpt这样的预训练模型。为了能够对生成模块进行生成效果的控制,我们使用提示学习的方法来进行控制,也就是在生成模块的输入前加入提示向量,提示向量能够对生成模块的模型起到提示作用,这就是提示模块的作用。提示模块中的提示向量是由控制模块产生的,控制模块通过从带有控制目的标签的历史数据中学习得到,生成具有控制效果的提示向量。

First, we introduce and explain the overall architecture of the framework, which includes three parts: the generation module, the prompt module, and the control module. The generation module is a decoder architecture that predicts the next token and generates text. It typically uses a pre-trained model like GPT. To enable control over the generation effect of the generation module, we use prompt learning methods for control. This means adding a prompt vector to the input of the generation module before generating the text. The prompt vector can provide hints to the model, which is the role of the prompt module. The prompt vector generated in the prompt module is produced by the control module through learning from historical data with controlled purpose labels. This generates a prompt vector with controlling effects.

1. Control Module

控制模块的输入是用户的个人特征信息和用户的历史数据,输出是用户是否进行点击行为的概率,用户是否对生成词进行点击代表了该用户的偏好,模型是用了Bert模型,因为Bert模型具有深层次的语义理解能力,能够对用户的历史行为数据进行深层次的语义理解和特征抽取。为了体现控制模块的控制作用,我们在考虑除了令控制模块生成体现用户偏好的高维特征向量之外,我们还考虑了生成式模型有非常严重的马太效应现象,因为生成式模型本质上是一个词概率预测模型,所以生成式模型会以更大概率生成在训练集中频繁出现的token,所以想要用控制模块在起到控制生成符合用户偏好结果之外同时能起到控制生成式模型的马太效应。所以在控制模块的Bert模型输出会输入到两个多层神经网络分类器进行多任务学习,一个分类器是用于区分用户是否进行点击,另一个分类器是用来区分用户是否会更倾向于点击低频词的生成结果。通过对用户个人信息和历史的行为数据进行建模,控制模块能够抽取到表征着用户偏好的特征向量。

The input to the control module is the personal feature information of the user and the user’s historical data, and the output is the probability of the user performing a click behavior. Whether the user clicks on the generated words represents the user’s preferences. The model uses the Bert model because the Bert model has deep semantic understanding capabilities and can perform deep semantic understanding and feature extraction on the user’s historical behavioral data. To reflect the controlling effect of the control module, in addition to letting the control module generate high-dimensional feature vectors reflecting user preferences, we also consider that the generative model has a severe Matthew effect phenomenon. Because the generative model is essentially a word probability prediction model, the generative model will predict tokens that appear frequently in the training set with a higher probability. Therefore, in addition to controlling the generation of user preference-conforming results, the control module can also control the Matthew effect of the generative model.Therefore, the output of the Bert model in the control module will be input to two multi-layer neural network classifiers for multi-task learning. One classifier is used to distinguish whether the user performs a click, and the other classifier is used to distinguish whether the user is more likely to click on the generated results of low-frequency words. By modeling the user’s personal information and historical behavior data, the control module can extract a feature vector representing the user’s preferences.

2. Prompt Module

提示模块主要由一个多层神经网络组成,将Bert抽取出来的高维特征映射到gpt模型的文本embedding空间中,并将控制模块生成的特征向量进行resize,并将特征向量作为提示与用户的输入embedding合并,之后一起输入到生成模块中。

3. Generation Module

生成模块的输入是提示模块的提示向量与用户的输入文本的向量,本文中生成模块的模型是GPT2,GPT2根据提示向量对用户输入文本进行结果补全,因为提示向量中蕴含的用户偏好特征情况下,GPT2模型能够生成更加符合用户偏好的结果,并且能够减少那些不热衷于高频商家的用户的马太效应。

Training Strategy

训练阶段分为两个个阶段:预训练、微调

预训练阶段分为两个部分:第一部分是对控制模块进行预训练,第二部分是对生成模块进行预训练

对控制模块预训练实际上是对预训练的Bert模型进行下游任务微调,将用户的用户特征和用户历史的输入和生成的item作为Bert模型的输入

微调阶段只要针对生成模块和提示模块,微调分为两个阶段:第一阶段只微调提示模块,生成模块的参数是冻结的;第二阶段是微调提示模块和生成模块。

Experiments

Experiment Settings

dataset

美团数据

AOL数据

Evaluation

BLEU-1、BLEU-2、BLEU-3、BLEU-4

基尼指数

Baselines

Implementation Details

Experimental Results

第一,在传统经典的生成式模型中,生成效果比较好的是Transformer模型,相比较与传统的RNN、CNN系列的生成模型,Transformer模型在自然语言建模上效果更好,所以在同样的数据集上进行训练,Transformer效果更好。甚至,Transformer模型的效果也要比不经过微调的GPT-2模型的效果要好,但是在UCTG框架下经过微调后的模型效果要好于其他所有模型

第二,与hard prompt 和 soft prompt 相比,在UTCG框架下微调的模型效果是更好的,从结果来看,hard prompt效果好于soft prompt,这是不符合常规逻辑的,但是综合QAC的具体场景和基于的底座模型来考虑,对于GPT-2这种参数量不大的底座模型,soft prompt的微调方法很难发挥出其特点,因为微调方法是依赖于底座模型的能力,如果底座模型的参数量越大,效果越好,那么经过soft prompt微调之后效果也会更好,相反,对于底座模型参数量小的情况,soft prompt可能会起到相反的作用。hard prompt的效果略好与未经微调的模型,这是因为hard prompt中有用户历史的点击item,能够对GPT-2起到一定的提示作用

第三,从基尼指数效果来看,经过UTCG(多任务)的提示微调的基尼指数要远远小于正常训练得到的模型,而且Transformer模型的基尼指数最高,这也说明Transformer模型非常依赖于token之间的关联度,其他的生成模型都不同程度的增强了生成的马太效应,而经过UTCG框架微调之后的模型基尼指数明显降低也证明了UTCG框架中控制模块抽取的embedding的有效性,并且可以看出,在经过多任务UTCG框架微调的GPT-2模型虽然在基尼指数上效果明显,但是在文本准确度上有所下降,这可能是因为控制模块生成的提示向量在信息容量不变的前提下无法做到将两种提示高维特征整合或者控制模块在多任务学习时更多地学习到了对马太效应的控制特征。

总的来说,经过UTCG框架微调过后的GPT-2模型能够在控制模块的定向提示下进行相应的文本控制,并且效果有明显地提升

原始的AOL查询日志包含用户输入的一系列查询以及时间戳详细信息。我们首先通过将所有查询转换为小写,删除重复和单个字符的查询,并删除具有占主导地位(>50%)的非字母数字字符的查询来预处理数据集。为了训练和评估QAC模型,大多数先前的工作从公共查询日志数据集中构建前缀-查询对作为正样本,通过拆分用户输入的完整查询,然后随机从候选池中选择一些查询构建负样本。这些数据集不包含任何真实的前缀到查询点击行为,但在实际的工业开发中,工程师通常使用前缀-查询对训练学习排序模型,其中包括用户输入的前缀和用户点击的完成查询作为正样本,其他对作为负样本。

原始的AOL quert log数据集只包含了用户的输入、用户是否有点击行为以及时间戳的信息,这些数据并无法直接表征出用户的输入、系统的query候选词、用户对系统query候选词的行为三者的关系,所以我们需要对AOL数据集进行一定的数据处理。我们首先将所有的用户真实输入全部转换为小写,删除重复和单个字符查询,并删除以非字母数字字符为主要输入的用户输入。之后对于每个用户的真实输入,随机取前几位作为用户的模拟输入,使用完整的用户输入作为模拟query,并随机从数据集中选择一些用户完整输入作为负样本,这样就构造出了包含用户输入、query候选词以及用户行为反馈的数据集。

Tables 3展示了模型在Meituan Query Log和AOL Query Log两个数据集上的指标效果

各个模型在AOL数据集上的效果趋势与在Meituan数据集上的大致相似,在传统生成模型中,Transformer在两个数据集上的效果都是最好的,与没有微调之前的GPT-2模型和freeze方式进行微调的GPT-2模型的效果差距很小,这说明了在两组实验上模型效果的一致性。在UTCG框架下微调之后的GPT-2模型,在Meituan数据集和AOL数据集市上都表现出了最好的效果,这说明了UTCG框架在不同数据集上的泛化性,证明了UTCG框架的有效性不是只出现在某个数据集上的,是具有普世性的。同时可以观察到,在Meituan数据集上UTCG框架微调的效果提升要明显高于在AOL数据集上的提升,这是因为Meituan数据集是垂直领域的数据集,文本数据都属于商品领域的数据,而AOL数据集的数据分布则要更为广泛,这导致UTCG在进行prompt生成的时候无法很好地生成符合控制条件的prompt。

Figure 1展示了UTCG框架不同微调和改变生成模块模型大小在不同测试数据量下的文本生成效果,通过控制其他模块不变,只改变生成模块GPT-2模型的大小,可以看出base大小下的UTCG整个的文本生成效果要明显好于distil大小下的UTCG,同时在不经过UTCG框架微调之前,base GPT-2的生成效果本身就要比distil GPT-2的效果要好,这说明在整个UTCG框架中,不同效果的模型作为生成模块会对整个UTCG框架的效果产生不同的影响,并且可以推断,越是效果好的模型作为生成模块,UTCG提示微调框架对模型效果的提升就越明显。另外,作用于不同大小的GPT-2,使用UTCG微调框架都取得了明显的提升,这也说明了UTCG微调效果的通用性和普适性。

Figure 2展示了UTCG微调框架和常规的两种prompt微调方法的对比效果。从实验结果可以看出,经过hard prompt微调后的模型效果较原模型有少量提升,但是经过soft prompt微调之后的模型效果却有所下降,UTCG微调框架的效果则有明显提升,原因有以下几种: 1) hard prompt和soft prompt的微调效果都依赖于所微调的模型效果本身,对于参数量很大的大模型,hard prompt和soft prompt能够在其基础上产生好的效果,但在本实验中GPT-2本身在电商特定领域数据集效果就不如在通用数据集上效果好,所以hard prompt和soft prompt在其基础之上就很难有较好的效果的提升 2)UTCG控制模块生成的提示向量是在用户历史行为数据作为反馈信号下生成的高维特征向量,该提示向量具有更准确的特征提示,所以尽管GPT-2模型对电商数据集不太熟悉,但依然能够对GPT-2模型起到文本控制生成的作用。

Figure 3展示了对UTCG控制模块的loss函数进行修改之后的效果对比。从基尼指数上来看,控制模块多loss生成的提示向量对GPT-2模型进行微调之后,在基尼指数上有明显的下降,这说明控制模块多loss下生成的提示向量能够对GPT-2模型产生相对应的控制效果,该消融实验也证明了UTCG框架的更深层次的价值,通过更换UTCG中控制模块的loss函数,控制模块便可以生成具有相对应的控制作用的提示向量,并对GPT-2模型产生控制作用。

Figure 3是使用了T-SNE对1000条数据和embedding 向量进行聚类和可视化,通过可视化的结果可以看出,对于1000条数据根据距离远近形成若干个小的簇,而每个簇代表了用户在输入前几个词时的用户偏好,以Figure5的左下角来举例,图中左下角形成了一个明显的簇,通过每个点对应的用户和用户输入信息来看,该簇包含了用户2907007597.0输入词是炸鸡提示词是、用户1533072098.0输入词是黄焖鸡提示词是、用户613293787.0输入词是炸鸡提示词是、用户40962466.0输入词是猪肚鸡提示词是等文本,从文本内容上来看,聚集到一起的embedding向量对应的用户输入都是跟鸡肉相关的食物,而且这几个用户的历史点击也是主要跟食物相关,这也再次验证了UCTG框架中控制模块对用户的爱好建模与人的普遍认知是一致,也再次说明了控制模块生成的embedding具有实际的意义,并且能够对GPT-2进行提示进而控制文本的生成。

Figure 4是使用了UMAP(Uniform Manifold Approximation and Projection),一种高维数据将为算法,对1000条文本数据和embedding进行可视化展示,UMAP相对于T-SNE能反映全局结构。从降维可视化的图中可以看出,尽管更换了可视化的算法,”用户2907007597.0输入词是炸鸡提示词是“、”用户2561854230.0输入词是烤鸡提示词是“,”用户2270230980输入词是鸡汤提示词是“等还是聚集到了一起,从这些文本中可以看出,输入词主要也是跟食物相关,并且这几个用户的历史点击也表明其偏好特点在食物方面

从上述两个聚类\降维算法得到的可视化结果可以看出,UCTG框架中控制模块的到的高维向量确实表征了用户的行为偏好和特点,这也验证了在具体试验中UCTG微调之后的模型效果明显的提升确实是由于提示向量的提示作用。

我们提出的UCTG框架由两个阶段组成:(i)用下游任务数据集预训练GPT-2模型和BERT模型 和(ii)提示调优。这两个阶段的优化使得UCTG框架在前一个阶段GPT-2学习下游领域的相关信息,BERT模型学习到用户的偏好和query出现的频次特点,然后在后一个阶段中利用BERT模型抽取出来的高维向量去微调GPT-2的文本生成,从而使得GPT-2模型能够生成对应控制效果的。

具体而言,在预训练阶段,GPT-2模型的参数和BERT模型的参数是发生改变的,这是因为GPT-2模型需要在下游数据上进行参数更新以学习到下游数据中的新的信息,BERT模型需要通过对用户行为反馈数据和Query出现的频次特点进行参数更新以便能抽取出具有高维特征的向量。并且,为了后续调优阶段中BERT模型抽取的向量更好地匹配GPT-2的语义空间,需要控制GPT-2模型的vocab与BERT模型的vocab一致。之后,在提示调优阶段,有两种参数更新方式,i)GPT-2模型的参数冻结,提示模块中的参数更新,进一步调整提示向量以适应下游领域任务。ii)GPT-2模型的参数和提示模块中的参数一同更新以更加完美地适应下游领域任务。

用户3170313953.0输入词是炸鸡提示词是、用户980125838.0输入词是参鸡提示词是、、用户277412824.0输入词是黄焖鸡提示词是、用户2561854230.0输入词是烤鸡提示词是、用户1885650741.0输入词是烧鸡公提示词是、用户3652156408.0输入词是白切鸡提示词是、用户1189562967.0输入词是火锅鸡提示词是、用户3155472689.0输入词是鸡精提示词是、用户412329645.0输入词是凉拌鸡提示词是、用户951668225.0输入词是蛙蛙鸡提示词是、用户3678392590.0输入词是瑶鸡提示词是、用户3803971217.0输入词是鸡提示词是、用户312910262.0输入词是黄焖鸡提示词是、用户700332224.0输入词是猪肚鸡提示词是

曝光度计算指标

生成式模型有个很大的问题就是,生成内容容易受训练数据中的文本频率影响,所以需要控制某个商家的曝光率,以及整个推荐的覆盖率和多样性

所以说,在生成式场景下,马太效应会更加明显

1. 七猫小说推荐系统的做法

添加了6个特征进行模型的训练

用户该书30内书籍曝光次数
userbook_show_count_14 用户该书14内书籍曝光次数
userbook_show_count_7 用户该书7内书籍曝光次数
userbook_click_count_30 用户该书30内书籍点击次数
userbook_click_count_14 用户该书14内书籍点击次数
userbook_click_count_7 用户该书7内书籍点击次数

2. 覆盖率与基尼系数

覆盖率用来衡量推荐的物品占总物品的比例
$$
Coverage = \frac{推荐的物品数}{总物品数}
$$
基尼系数描述的是物品流行度的分布趋势
$$
G=1-\frac{1}{n}\left(2 \sum_{i=1}^{n-1} w_i+1\right)
$$

3. 商品出现次数

统计某个商品在一段时间内的出现次数占所有出现次数的比值作为该商品的曝光度

或者是基于历史数据算出某个商品下次出现的概率作为商品的曝光度, 可以使用贝叶斯概率计算

评审意见

写作问题

  1. Authors made several expiations for their experiment results, but from the results, it contradicts what authors explained.

  2. In addition, authors observed the contradict result when comparing soft prompt and hard prompt, the explanation was not quite convincible.

  3. Selected architecture is not well motivated compared to similar more flexible approaches like RAG

  4. missed an important span of work that would have beeen totally relevant for the presented use-case

    Learning to Write with Cooperative Discriminators

  5. This paper is not well-written and not presented effectively in appropriate format. Some typos are found and also the presentation of figures (like Figure 3) can be improved.

  6. There are some typos in the paper, i.e. in section 3.2 first paragraph, Figure index was missing.

实验问题

  1. Since this is a framework, authors should present more variety datasets to prove this framework work on different domains and datasets, only one specific domain which cannot persuade audience to believe this framework will work for other domains or tasks.
  2. experiments section heavily focuses on different variations of the same method
  3. designed architecture is not flexible and would require retraining given changes in base models
  4. outdated generative model (GPT2) in the experiments make the reader wonder what would be the results with more capable and versatile generative models
  5. failed to showcase the flexibility of the approach: flexibility is cited as an advantage of the approach, but not highlighted in the experiments
  6. More recent baselines can be chosen. The paper lacks comparisons and discussions with widely-known baselines in the field, which hinders the assessment of the novelty and performance of UCTG.
  7. This paper is not well-written and not presented effectively in appropriate format. Some typos are found and also the presentation of figures (like Figure 3) can be improved.

作者: Sagar Sharma 译者: ChatGPT

| 2023-06-30 10:26   评论: 3    

在这份超详细的指南中了解如何通过 i3 窗口管理器来自定义系统的外观和体验。

你可能在网上(尤其是通过 r/unixporn 子区)看到过很多炫酷的截图,用户可以根据个人喜好自定义他们的桌面并与大家分享。

这是因为 Linux 允许你自定义桌面体验的方方面面。

而结果?就是比任何 Mac 或 Windows 系统更具视觉和感知效果

来看一下这个 😌

看起来像一个 Linux Mint 系统吗? 😲

但是你怎样才能做到这样呢?自定义你的 Linux 桌面外观是很困难的

答案就在于 窗口管理器。如果你能配置好窗口管理器,你就能自定义外观。

在本指南中,我将引导你完成使用 i3 窗口管理器 进行基本配置。它是 Linux 上最好的窗口管理器之一

💡 “加料Rice” 是一个常用的词汇,用来指代在桌面上进行视觉改进和自定义。引用自 /r/unixporn (LCTT 译注:“加料”一词来自于购买便宜的亚洲汽车,并给它们安装售后零件,以让它更好地类似于赛车。)

在遵循本指南之前,你需要了解以下内容:

  • 在本指南中,我将使用 Arch Linux 来演示步骤,但你可以使用你喜欢的任何发行版,结果也是一样的。
  • 请记住,本指南是 对 i3 进行“加料”定制的基础

在按照本指南进行操作后,你应该得到以下预期结果:

如何在 Linux 中配置 i3 窗口管理器、i3blocks 和 i3gaps

📥 为了节省你的时间,我已经在 GitHub 上上传了与本文相关的所有 i3 配置文件,你可以通过这些文件实现我们在本文中所期望的最终外观。

下载 i3 配置文件

首先,让我们开始安装 i3 窗口管理器

在 Linux 上安装 i3 窗口管理器

基于 Ubuntu/Debian:

1
sudo apt install xorg lightdm lightdm-gtk-greeter i3-wm i3lock i3status i3blocks dmenu terminator

Arch Linux:

1
sudo pacman -S xorg lightdm lightdm-gtk-greeter i3-wm i3lock i3status i3blocks dmenu terminator

当你完成安装后,使用以下命令启用 lightdm 服务:

1
sudo systemctl enable lightdm.service

然后启动 lightdm 服务:

1
sudo systemctl start lightdm.service

这将启动 lightdm 登录界面,并要求你输入用户名密码。

如果你安装了多个桌面环境,你可以从选择菜单中选择 i3:

在 Arch Linux 上使用 lightdm 使用 i3 窗口管理器

当首次登录 i3 时,它会询问你是否要创建一个 i3 配置文件。

按下回车键创建一个新的 i3 配置文件:

生成 i3 配置文件

接下来,它会询问你选择 Win 或 Alt 键哪个作为修饰键(mod)。

我建议你选择 Win(或者 Super 键),因为大多数用户已经习惯将其用作快捷键:

现在你可以开始使用 i3 窗口管理器了。

但在我们开始定制之前,让我先介绍一下你如何使用 i3。

i3 窗口管理器的按键绑定

让我们从基础知识开始。

窗口管理器的基本功能是将多个窗口水平和垂直地组合在一起,这样你就可以同时监视多个进程。

结果是这样的:

在 Arch Linux 上使用 i3

你可以使用以下按键绑定执行更多操作:

按键绑定 描述
Mod + Enter 打开终端。
Mod + ← 切换到左侧窗口。
Mod + → 切换到右侧窗口。
Mod + ↑ 切换到上方窗口。
Mod + ↓ 切换到下方窗口。
Mod + Shift + ← 将窗口移动到左侧。
Mod + Shift + → 将窗口移动到右侧。
Mod + Shift + ↑ 将窗口移动到上方。
Mod + Shift + ↓ 将窗口移动到下方。
Mod + f 将焦点窗口切换到全屏模式。
Mod + v 下一个窗口将垂直放置。
Mod + h 下一个窗口将水平放置。
Mod + s 启用堆叠式窗口布局。
Mod + w 启用选项卡式窗口布局。
Mod + Shift + Space 启用浮动窗口(针对焦点窗口)。
Mod + 鼠标左键单击 使用鼠标拖动整个窗口。
Mod + 0-9 切换到另一个工作区。
Mod + Shift + 0-9 将窗口移动到另一个工作区。
Mod + d 打开应用程序启动器(D 菜单)。
Mod + Shift + q 关闭焦点窗口。
Mod + Shift + c 重新加载 i3 配置文件。
Mod + Shift + r 重启 i3 窗口管理器。
Mod + Shift + e 退出 i3 窗口管理器。

我知道按键绑定很多,但如果你每天练习它们,你很快就会习惯。

如果你想知道,你可以根据需要更改按键绑定,后面的指南中我会分享如何做到这一点。

现在,让我们来看看配置部分。

在 Arch Linux 中启用 AUR

如果你刚刚安装了 Arch Linux,可能还没有启用 AUR。

这意味着你错过了 Arch Linux 最重要的特性。

要 启用 AUR,你需要使用 AUR 包管理器。在这里,我将使用 yay

首先,安装 git

1
sudo pacman -S git

现在,克隆 yay 存储库并切换到 yay 目录:

1
git clone https://aur.archlinux.org/yay-git.git && cd yay

最后,构建包:

1
makepkg -si

还有其他一些 AUR 包管理器,比如 Paru,如果你想使用除 yay 之外的其他工具,你可以继续或者探索其他选项。

更改 i3 窗口管理器的分辨率

如果你使用虚拟机运行窗口管理器,可能会遇到问题,尤其是显示分辨率可能被锁定在 1024x768 上,就像我一样。

因此,你需要执行以下命令,指定所需的显示分辨率:

1
xrandr --output [显示名称] --mode [分辨率]

要找到已连接显示器的名称,你需要使用以下形式的 xrandr 命令:

1
xrandr | grep -w 'connected'

在 i3 中查找已连接显示器

在我的情况下,显示名称是 Virtual-1

因此,如果我想将分辨率更改为 1920*1080,我需要执行以下命令:

1
xrandr --output Virtual-1 --mode 1920x1080

但这只是暂时生效。要使其永久生效,你需要在 i3 配置文件中进行更改。

首先,打开配置文件:

1
nano ~/.config/i3/config

通过按下 Alt + / 来在 nano 中 跳到文件末尾,并使用以下语法来永久更改显示分辨率:

1
2
# 显示分辨率
exec_always xrandr --output [显示名称] --mode [分辨率]

结果应该是这样的:

在 i3 中永久更改显示分辨率

完成后,保存更改并退出 nano 文本编辑器。

现在,使用 Mod + Shift + r 重新启动 i3 窗口管理器,以使你对配置文件所做的更改生效!

在 i3 窗口管理器中更改壁纸

默认情况下,i3 的外观比较陈旧,你可能想切换回之前的桌面环境。

但是通过更改壁纸,你可以改变整个系统的氛围。

在 i3 中有多种方式可以更改壁纸,但在这里,我将向你展示如何使用 feh 实用工具。

首先,让我们从安装开始:

对于基于 Arch 的发行版

1
sudo pacman -S feh

对于 Ubuntu/Debian 系的发行版:

1
sudo apt install feh

安装完成后,你可以从互联网上下载你喜欢的壁纸。接下来,打开 i3 配置文件

1
nano ~/.config/i3/config

跳到文件的末尾,使用如下所示的 feh 命令:

1
2
# 显示壁纸
exec_always feh --bg-fill /path/to/wallpaper

在我的情况下,壁纸位于 Downloads 目录中,所以我的命令如下:

使用 feh 实用工具在 I3 窗口管理器中更改背景

保存更改并退出 nano 文本编辑器。

为了使配置文件的更改生效,使用 Mod + Shift + r 重新启动 i3 窗口管理器。

我的效果如下:

在 i3 窗口管理器中更改壁纸

自定义 i3 锁屏界面

默认情况下,如果你想锁定系统,你需要执行以下命令:

1
i3lock

锁屏界面如下所示:

锁定 i3 窗口管理器

下面,我将向你展示:

  • 如何创建自定义快捷方式以锁定 i3 会话
  • 如何更改锁屏界面的壁纸

为了使锁屏界面更加美观,你需要使用 i3lock-color 包。

但首先,你需要移除现有的 i3lock,因为它会与 i3lock-color 冲突:

在 Arch Linux 上移除它:

1
sudo pacman -R i3lock

对于 Ubuntu/Debian 用户:

1
sudo apt remove i3lock

完成后,你可以使用 AUR 包管理器安装 i3lock-color

1
yay i3lock-color

如果你使用的是基于 Ubuntu 的系统,你需要从头编译它。你可以在他们的 GitHub 页面上找到 详细的说明

安装完成后,让我们创建一个新目录并创建一个新文件来存储锁屏界面的配置:

安装好 i3lock-color 后,你可以创建一个新目录并创建一个新文件来存储锁屏界面的配置:

1
mkdir ~/.config/scripts && nano ~/.config/scripts/lock

将以下文件内容粘贴到文件中,定义锁屏界面的样式:

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
#!/bin/sh

BLANK='#00000000'
CLEAR='#ffffff22'
DEFAULT='#00897bE6'
TEXT='#00897bE6'
WRONG='#880000bb'
VERIFYING='#00564dE6'

i3lock \
--insidever-color=$CLEAR \
--ringver-color=$VERIFYING \
\
--insidewrong-color=$CLEAR \
--ringwrong-color=$WRONG \
\
--inside-color=$BLANK \
--ring-color=$DEFAULT \
--line-color=$BLANK \
--separator-color=$DEFAULT \
\
--verif-color=$TEXT \
--wrong-color=$TEXT \
--time-color=$TEXT \
--date-color=$TEXT \
--layout-color=$TEXT \
--keyhl-color=$WRONG \
--bshl-color=$WRONG \
\
--screen 1 \
--blur 9 \
--clock \
--indicator \
--time-str="%H:%M:%S" \
--date-str="%A, %Y-%m-%d" \
--keylayout 1 \

保存更改并退出文本编辑器。

📋 在网上可以找到各种不同的 i3 锁屏样式的 bash 脚本。这只是一个示例,对于大多数情况来说是一个较为简单的选项。

现在,使用 chmod 命令 将该文件设置为可执行文件:

1
sudo chmod +x .config/scripts/lock

接下来,你需要对配置文件进行一些更改,以添加该配置文件的路径以使其生效。

此外,我将向你展示如何使用自定义键盘快捷键锁定屏幕。

首先,打开配置文件:

1
nano ~/.config/i3/config

使用 Alt + / 跳至行尾并粘贴以下内容:

1
2
# 锁屏快捷键
bindsym $mod+x exec /home/$USER/.config/scripts/lock

在上面的示例中,我将 mod + x 作为锁定屏幕的快捷键,你可以选择任何你喜欢的快捷键。

最后的配置文件将如下所示:

如何在 Arch Linux 中使用 i3lock-color

相当不错,不是吗?

在 i3 窗口管理器中更改主题和图标

我知道你可能会想到这个问题。

你为什么需要图标呢?你并不仅仅使用窗口管理器来使用命令行工具。

有时候,使用图形界面更加方便,比如使用文件管理器。所以,在处理这些工具时,你希望界面看起来更好看?

因此,在本部分中,我将向你展示:

  • 如何在 i3 中更改主题
  • 如何在 i3 中更改图标

让我们从安装主题开始。

在这里,我将使用 materia-gtk-theme 和 papirus 图标,但你可以使用任何你喜欢的主题和图标。

在 Arch 中安装主题,使用以下命令:

1
sudo pacman -S materia-gtk-theme papirus-icon-theme

在 Ubuntu/Debian 系统中:

1
sudo apt install materia-gtk-theme papirus-icon-theme

但仅仅安装还不能完成任务。你需要像使用 GNOME “调整Tweaks” 应用更改主题一样来应用主题。

在 i3 中,你可以使用 lxappearance 工具 来更改主题和图标。

在 Arch 中安装 lxappearance,使用以下命令:

1
sudo pacman -S lxappearance

在 Ubuntu/Debian 系统中:

1
sudo apt install lxappearance

安装完成后,使用 Mod + d 启动 D 菜单,然后输入 lxappearance,并在第一个结果上按回车键。

在这里,选择你喜欢的主题。我这里选择 Materia-dark

选择主题后,点击应用按钮以应用更改:

同样地,要更改图标,选择 “图标主题Icon Theme”,选择图标主题,然后点击应用按钮:

使用 lxappearance 更改 i3 窗口管理器中的图标

应用主题和图标后,我的文件管理器如下所示:

在 i3 窗口管理器中更改主题和图标

在 i3 窗口管理器中为工作区设置图标

默认情况下,工作区仅由数字表示,这并不是你想要使用工作区的最理想方式。

因此,在本部分中,我将引导你如何使用合适的图标更改工作区的名称。

为了在配置文件中使用图标,首先你需要安装名为 Awesome 的新字体:

对于基于 Arch 的发行版:

1
sudo pacman -S ttf-font-awesome

对于 Ubuntu/Debian 系统:

1
sudo apt install fonts-font-awesome

安装完成后,打开 i3 配置文件:

1
nano ~/.config/i3/config

在这个配置文件中,找到工作区的部分,你将会看到为每个工作区给出的变量:

在 i3 配置文件中的工作区变量

在这个部分,你需要用你想要的名称替换给出的工作区数字。

我将把第一个工作区命名为 “programs”,因为在本教程的后面部分,我将展示如何将特定的应用程序分配到特定的工作区。

我主要使用前 5 个工作区,所以我会相应地命名它们:

1
2
3
4
5
6
7
8
9
10
11
12
# 定义默认工作区的名称,稍后我们将在其中配置键绑定。
# 我们使用变量来避免在多个地方重复使用名称。
set $ws1 "1: Terminal"
set $ws2 "2: Firefox"
set $ws3 "3: VMWare"
set $ws4 "4: Spotify"
set $ws5 "5: Shutter"
set $ws6 "6"
set $ws7 "7"
set $ws8 "8"
set $ws9 "9"
set $ws10 "10"

现在让我们为配置文件中提到的每个应用程序添加图标。

你可以 参考 awesome 字体的备忘单 来找到合适的图标。

将图标复制粘贴到名称前面:

1
2
3
4
5
6
7
8
9
10
11
12
# 定义默认工作区的名称,稍后我们将在其中配置键绑定。
# 我们使用变量来避免在多个地方重复使用名称。
set $ws1 "1:  Terminal"
set $ws2 "2:  Firefox"
set $ws3 "3:  VMWare"
set $ws4 "4:  Spotify"
set $ws5 "5:  Shutter"
set $ws6 "6"
set $ws7 "7"
set $ws8 "8"
set $ws9 "9"
set $ws10 "10"

不要担心它看起来可怕!

完成后,使用 Mod + e 退出 i3,然后再次登录以应用你刚刚所做的更改。

我的效果如下图所示:

字体看起来太小?是时候解决这个问题了!

在 i3 中更改标题窗口和状态栏的字体

首先,让我们安装新的字体(我将在这里使用 Ubuntu 字体)。

要在 Arch 上安装 Ubuntu 字体,请执行以下操作:

1
sudo pacman -S ttf-ubuntu-font-family

如果你使用的是 Ubuntu,你已经安装了这些字体!

安装完成后,打开配置文件:

1
nano ~/.config/i3/config

在配置文件中,找到 font pango:monospace 8 这一行,这是默认字体。

找到那行后,添加字体名称和大小,如下所示:

1
font pango:Ubuntu Regular 14

然后,使用 Mod + Shift + r 重新启动窗口管理器,这样就完成了工作:

在 i3 窗口管理器中分配应用程序到工作区

在给工作区命名之后,你会想要将特定的软件分配到相应的工作区中。

例如,如果我将第二个工作区命名为 “Firefox”,那么我只想在该工作区中使用 Firefox。

那么要如何实现呢?

为了做到这一点,你需要找到每个要分配的应用程序的类名。

听起来复杂? 让我告诉你如何做。

首先,将应用程序和终端并排打开。例如,在这个例子中,我将 Firefox 和终端并排打开:

并排打开应用程序和终端

现在,在终端中执行 xprop 命令,它会改变鼠标指针的形状:

1
xprop

接下来,将鼠标悬停在应用程序上,并在应用程序窗口内的任何位置单击,如图所示:

在 i3 窗口管理器中查找类名

类名将在以下行的最后一个字符串中找到:

1
WM_CLASS(STRING) = "Navigator", "firefox"

在我的情况下,Firefox 浏览器的类名将是 firefox

对所有你想要分配到工作区的应用程序重复这个过程。

一旦你知道每个你想要分配到工作区的应用程序的类名,打开配置文件:

1
nano ~/.config/i3/config

使用 Alt + / 将 nano 定位到文件末尾,并使用以下语法将应用程序分配到工作区:

1
2
# 分配应用到工作区
for_window [class="类名"] move to workspace $[工作区变量]

作为参考,下面是我为不同应用程序分配了 4 个工作区后的配置文件示例:

将应用分配到工作区

现在,无论在哪个工作区打开任何应用程序,它都会自动放置在配置的工作区中。非常方便! 😊

在 i3 窗口管理器中让终端变透明

要启用透明效果,你需要安装 picom 合成器并对配置文件进行一些更改。

让我们从安装开始。

对于基于 Arch 的发行版:

1
sudo pacman -S picom

对于基于 Ubuntu/Debian 的发行版:

1
sudo apt install picom

安装完成后,你需要告诉系统使用 picom

首先打开配置文件:

1
nano ~/.config/i3/config

在配置文件的末尾插入以下行:

1
2
# 使用 picom 合成器实现透明效果
exec_always picom -f

这里,我使用 -f 标志来在切换工作区、打开新应用程序等时启用淡入淡出效果。

保存并退出文本编辑器。

现在,使用 Mod + Shift + r 重新启动 i3。

接下来,打开终端,打开 “首选项Preference”,然后选择“配置文件Profiles”,选择“背景Background”,然后选择“透明背景Transparent background”选项。

从这里,你可以调整透明度:

在 i3 窗口管理器中更改终端背景透明度

在 i3 窗口管理器中自定义状态栏

默认情况下,状态栏显示各种信息,但没有图标。

因此,在这个部分,我将展示如何从状态栏中删除一些元素以及如何为它们添加图标。

但是,在这里,我将在 /etc/i3status.conf 中创建一个原始状态栏的副本,以便如果出现任何错误,你可以随时恢复到默认配置。

首先,在 .config 目录下创建一个新的目录:

1
mkdir .config/i3status

在以下命令中,我使用了 cp 命令来复制文件

1
sudo cp /etc/i3status.conf ~/.config/i3status/i3status.conf

接下来,使用 chown 命令更改所有者,以便你可以进行所需的更改:

1
sudo chown $USER:$USER ~/.config/i3status/i3status.conf

现在,你需要通过修改 i3 配置文件来指示窗口管理器使用新的 i3status 配置文件。首先打开配置文件:

1
nano ~/.config/i3/config

在该配置文件中查找 status_command i3status 这一行。这是你将提供新状态配置文件路径的行。

找到该行后,进行以下更改:

1
2
3
bar {
status_command i3status -c /home/$USER/.config/i3status/i3status.conf
}

最终的结果应该如下所示:

在 i3 窗口管理器中更改 i3 状态配置路径

保存更改并退出文本编辑器。

现在,让我们从状态栏中删除不必要的指示器。

首先,打开 i3status 配置文件:

1
nano .config/i3status/i3status.conf

在这里,你可以将以 order 开头的行注释掉,这些行实际上是指示器的变量。

例如,在这里,我禁用了 ipv6wireless _first_battery all 和 load 这些对我来说不必要的指示器:

1
2
3
4
5
6
7
8
#order += "ipv6"
#order += "wireless _first_"
order += "ethernet _first_"
#order += "battery all"
order += "disk /"
#order += "load"
order += "memory"
order += "tztime local"

然后,在浏览器中打开 awesome font 列表,找到与状态栏中列出的项目相关的适当图标。

在我的设置中,我删除了以下内容:

  • 删除了显示可用内存的行
  • 删除了显示以太网连接速度的行

最终,我的状态栏如下所示:

自定义 i3 窗口管理器中的状态栏

在 i3 窗口管理器中改变颜色方案

更改 i3 窗口管理器中的颜色方案是这个指南中最重要的部分,因为窗口管理器最吸引人的地方就是你选择的窗口装饰颜色。

📋 我将为每个颜色声明变量,这样你只需更改变量本身的值,就可以轻松地获得新的颜色方案。

首先,打开 i3 配置文件:

1
nano ~/.config/i3/config

使用 Alt + / 快捷键到达文件末尾,并使用以下语法添加变量来存储颜色:

1
2
3
4
5
6
7
8
9
10
11
12
# 窗口的色彩方案
set $bgcolor #523d64
set $in-bgcolor #363636
set $text #ffffff
set $u-bgcolor #ff0000
set $indicator #a8a3c1
set $in-text #969696
# 边框 背景 文本 指示器(显示下一个窗口位置的线条)
client.focused $bgcolor $bgcolor $text $indicator
client.unfocused $in-bgcolor $in-bgcolor $in-text $in-bgcolor
client.focused_inactive $in-bgcolor $in-bgcolor $in-text $in-bgcolor
client.urgent $u-bgcolor $u-bgcolor $text $u-bgcolor

在这里:

  • bgcolor 表示背景色。
  • in-bgcolor 表示非活动窗口的背景色。
  • text 是文本颜色。
  • u-bgcolor 表示紧急操作的背景色。
  • indicator 是标示下一个窗口位置的线条的颜色。
  • in-text 是非活动窗口的文本颜色。

对于本指南,我仅使用了四个基本类别:

  • client.focused 定义了焦点窗口的颜色。
  • client.unfocused 定义了失去焦点时窗口的装饰。
  • client.focused_inactive 当其中一个容器处于焦点但当前没有焦点时,显示的颜色。
  • client.urgent 定义了紧急操作时的颜色。

💡 除了这四个类别,还有更多类别,请参考 官方 i3 配置手册 以了解更多信息。

一旦你对配置文件进行了更改,请使用 Mod + Shift + r 重新启动 i3。

如果你按照我的颜色方案,设置应该如下所示:

更改 I3 窗口管理器中的窗口颜色

那么,状态栏的颜色怎么办?当然可以改!

更改 i3 窗口管理器中状态栏的颜色方案

在本节中,你将意识到为什么我使用变量来存储颜色,因为我将使用相同的变量来为我的状态栏上色!

要在状态栏中使用颜色,你需要在 i3 配置文件的 bar {...} 部分进行更改。

首先,打开配置文件:

1
nano ~/.config/i3/config

在配置文件中查找 bar {...} 部分。

找到该部分后,创建一个颜色部分,并为状态栏定义颜色和类别,与你为窗口所做的相同:

1
2
3
4
5
6
7
8
9
10
11
12
bar {
status_command i3status -c /home/$USER/.config/i3status/i3status.conf
colors {
background $bgcolor
separator #191919
# border background text
focused_workspace $bgcolor $bgcolor $text
inactive_workspace $in-bgcolor $in-bgcolor $text
urgent_workspace $u-bgcolor $u-bgcolor $text

}
}

在这里,我使用了 focused_workspaceinactive_workspace 和 urgent_workspace 这三个类别,根据需要定义了相应的颜色。

保存更改后,重新启动 i3,状态栏也会显示颜色。

设置 i3 状态栏的透明度

本节将向你展示如何使 i3 状态栏透明。

在此之前,让我们先更改 i3 状态栏的字体。

这里,我将使用 Droid 字体,使其看起来干净而带有一种极客风格。

要在 Arch Linux 上安装 Droid 字体,请使用以下命令:

1
sudo pacman -S ttf-droid

对于 Ubuntu/Debian 系统,请使用以下命令:

1
sudo apt install fonts-droid-fallback

安装完成后,打开配置文件:

1
nano ~/.config/i3/config

进入 bar {...} 部分,并按下面的示例输入字体名称和大小:

1
font pango: Droid Sans Mono 11

在 i3 状态栏中更改字体

完成后,请重新启动 i3,字体将会被更改!

要使状态栏透明,你可以使用现有十六进制代码中的额外两个数字来定义透明度。

如果你想要控制透明度,我建议你查看 此指南,其中提供了从 0 到 100% 透明度的代码范围

为此,我将在配置文件中使用两个新变量。首先,打开配置文件:

1
nano ~/.config/i3/config

在这里,我为背景颜色添加了 60% 的透明度,并为非活跃背景颜色添加了 30% 的透明度:

1
2
set $bgcolor    #523d6499
set $in-bgcolor #3636364D

如果你仔细观察,我在现有的十六进制颜色代码中添加了两位数字来定义透明度。例如,使用 99 来表示 60% 的透明度,而使用 4D 来表示 30% 的透明度。

此外,我添加了两个新变量,透明度不同但颜色相同,作为背景使用,使其看起来更好:

1
2
set $focused-ws #523d6480
set $bar-color #523d640D

完成后,让我们修改 bar {...} 部分来应用透明度。

在 bar {...} 中添加两行代码:

1
2
i3bar_command i3bar --transparency
tray_output none

请注意,使用 tray_output none,它将不会在托盘中显示任何图标。如果你不希望出现这种行为,则可以跳过此行,只添加第一行以实现透明度。

一旦完成,修改状态栏的颜色方案,例如更改背景颜色、边框和活动工作区的背景。

修改后,配置文件应如下所示:

使 i3 状态栏透明的配置文件(i3 窗口管理器)

为了使你所做的更改生效,请重新启动 i3,你将得到透明的窗口和状态栏:

在 i3 窗口管理器中使状态栏和窗口透明

在窗口管理器中使用 i3blocks

默认的 i3 状态栏在我看来毫无用处;怎么样让它变得有用起来呢?

在本部分,我将解释如何添加以下功能:

  • 软件包更新
  • 内存使用情况
  • 磁盘使用情况
  • 音量指示器
  • Spotify 指示器

📋 要实现这些功能,你需要使用一些脚本,这些脚本将允许你向状态栏添加所需的操作。不用担心,我不会让你手动输入脚本;GitHub 上有各种脚本可供选择,几乎涵盖了你所需的所有方面。

但在此之前,你需要进行一些配置,以存储脚本并指示 i3 使用 i3block 的配置,而不是使用 i3bar。

如果你在本指南的开头按照给定的说明进行操作,那么 i3blocks 已经安装好了,并且配置文件位于 /etc/i3blocks.conf

如果你希望快速下载块配置文件以进行设置而不阅读其他内容,请点击以下链接:

i3 配置文件

在本教程中,我将创建一个副本,使用它代替原始的配置文件,因此首先我们要创建一个目录来存储配置文件的副本:

1
mkdir ~/.config/i3blocks

现在,创建一个原始配置文件的副本:

1
sudo cp /etc/i3blocks.conf ~/.config/i3blocks/

最后,使用 chown 命令更改文件的所有者,以便你进行所需的更改:

1
sudo chown $USER:$USER ~/.config/i3blocks/i3blocks.conf

要启用 i3blocks,在 i3 配置文件中进行一些更改:

1
nano ~/.config/i3/config

进入 bar {...} 部分,在这里,你需要将 status_command 更改为 i3blocks 并添加 i3blocks 配置文件的路径,如下所示:

在 i3 窗口管理器中启用 i3blocks

完成后,使用 Mod + Shift + r 重新启动 i3 窗口管理器,整个状态栏都会被更改,并显示如下:

i3 窗口管理器中 i3blocks 的默认外观

不要担心,你将很快使状态栏比以前的 i3bar 更有价值和好看。

添加磁盘块

如果你想要显示磁盘剩余空间,可以添加此块。

在这里,我将使用 nano 创建并打开用于磁盘块的配置文件。

1
nano ~/.config/scripts/disk

然后粘贴以下行:

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
#!/usr/bin/env sh
DIR="${DIR:-$BLOCK_INSTANCE}"
DIR="${DIR:-$HOME}"
ALERT_LOW="${ALERT_LOW:-$1}"
ALERT_LOW="${ALERT_LOW:-10}" # color will turn red under this value (default: 10%)

LOCAL_FLAG="-l"
if [ "$1" = "-n" ] || [ "$2" = "-n" ]; then
LOCAL_FLAG=""
fi

df -h -P $LOCAL_FLAG "$DIR" | awk -v label="$LABEL" -v alert_low=$ALERT_LOW '
/\/.*/ {
# full text
print label $4
# short text
print label $4
use=$5
# no need to continue parsing
exit 0
}
END {
gsub(/%$/,"",use)
if (100 - use < alert_low) {
# color
print "#FF0000"
}
}
'

保存更改并从文本编辑器中退出。

现在,将此文件设置为可执行:

1
sudo chmod +x ~/.config/scripts/disk

接下来,打开 I3blocks 配置文件:

1
nano ~/.config/i3blocks/i3blocks.conf

根据你想要放置磁盘块的位置,粘贴以下行:

1
2
3
4
5
6
[disk]
command=/home/$USER/.config/scripts/disk
LABEL=
#DIR=$HOME
#ALERT_LOW=10
interval=30

完成后,保存更改并使用 Mod + Shift + r 重新启动 i3,状态栏中将显示带有磁盘图标的可用磁盘空间。

添加内存块

这将是状态栏中指示系统中已使用内存的块。

首先,创建并打开一个新文件用于新的块:

1
nano ~/.config/scripts/memory

然后在新文件中粘贴以下行:

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
#!/usr/bin/env sh
TYPE="${BLOCK_INSTANCE:-mem}"
PERCENT="${PERCENT:-true}"

awk -v type=$TYPE -v percent=$PERCENT '
/^MemTotal:/ {
mem_total=$2
}
/^MemFree:/ {
mem_free=$2
}
/^Buffers:/ {
mem_free+=$2
}
/^Cached:/ {
mem_free+=$2
}
/^SwapTotal:/ {
swap_total=$2
}
/^SwapFree:/ {
swap_free=$2
}
END {
if (type == "swap") {
free=swap_free/1024/1024
used=(swap_total-swap_free)/1024/1024
total=swap_total/1024/1024
} else {
free=mem_free/1024/1024
used=(mem_total-mem_free)/1024/1024
total=mem_total/1024/1024
}
pct=0
if (total > 0) {
pct=used/total*100
}
# full text
if (percent == "true" ) {
printf("%.1fG/%.1fG (%.f%%)\n", used, total, pct)
} else {
printf("%.1fG/%.1fG\n", used, total)
}
# short text
printf("%.f%%\n", pct)
# color
if (pct > 90) {
print("#FF0000")
} else if (pct > 80) {
print("#FFAE00")
} else if (pct > 70) {
print("#FFF600")
}
}
' /proc/meminfo

保存更改并从文本编辑器中退出。

现在,要使其生效,你需要使用以下命令将此文件设置为可执行:

1
sudo chmod +x ~/.config/scripts/memory

接下来,打开 i3blocks 配置文件:

1
nano ~/.config/i3blocks/i3blocks.conf

并将以下内容粘贴到你希望在状态栏中显示内存使用情况的位置:

1
2
3
4
[memory]
command=/home/$USER/.config/scripts/memory
label=
interval=30

保存更改并从文本编辑器中退出。重新启动 i3 以使更改生效!

添加更新指示块

这是最有帮助的指示器,它显示需要更新的旧软件包数量。

首先,使用以下命令安装依赖项以使其正常工作:

1
sudo pacman -S pacman-contrib

现在,创建一个新文件来存储脚本:

1
nano ~/.config/scripts/arch-update

然后粘贴以下内容:

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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/env python3
import subprocess
from subprocess import check_output
import argparse
import os
import re


def create_argparse():
def _default(name, default='', arg_type=str):
val = default
if name in os.environ:
val = os.environ[name]
return arg_type(val)

strbool = lambda s: s.lower() in ['t', 'true', '1']
strlist = lambda s: s.split()

parser = argparse.ArgumentParser(description='Check for pacman updates')
parser.add_argument(
'-b',
'--base_color',
default = _default('BASE_COLOR', 'green'),
help='base color of the output(default=green)'
)
parser.add_argument(
'-u',
'--updates_available_color',
default = _default('UPDATE_COLOR', 'yellow'),
help='color of the output, when updates are available(default=yellow)'
)
parser.add_argument(
'-a',
'--aur',
action = 'store_const',
const = True,
default = _default('AUR', 'False', strbool),
help='Include AUR packages. Attn: Yaourt must be installed'
)
parser.add_argument(
'-y',
'--aur_yay',
action = 'store_const',
const = True,
default = _default('AUR_YAY', 'False', strbool),
help='Include AUR packages. Attn: Yay must be installed'
)
parser.add_argument(
'-q',
'--quiet',
action = 'store_const',
const = True,
default = _default('QUIET', 'False', strbool),
help = 'Do not produce output when system is up to date'
)
parser.add_argument(
'-w',
'--watch',
nargs='*',
default = _default('WATCH', arg_type=strlist),
help='Explicitly watch for specified packages. '
'Listed elements are treated as regular expressions for matching.'
)
return parser.parse_args()


def get_updates():
output = ''
try:
output = check_output(['checkupdates']).decode('utf-8')
except subprocess.CalledProcessError as exc:
# checkupdates exits with 2 and no output if no updates are available.
# we ignore this case and go on
if not (exc.returncode == 2 and not exc.output):
raise exc
if not output:
return []

updates = [line.split(' ')[0]
for line in output.split('\n')
if line]

return updates


def get_aur_yaourt_updates():
output = ''
try:
output = check_output(['yaourt', '-Qua']).decode('utf-8')
except subprocess.CalledProcessError as exc:
# yaourt exits with 1 and no output if no updates are available.
# we ignore this case and go on
if not (exc.returncode == 1 and not exc.output):
raise exc
if not output:
return []

aur_updates = [line.split(' ')[0]
for line in output.split('\n')
if line.startswith('aur/')]

return aur_updates

def get_aur_yay_updates():
output = check_output(['yay', '-Qua']).decode('utf-8')
if not output:
return []

aur_updates = [line.split(' ')[0] for line in output.split('\n') if line]

return aur_updates


def matching_updates(updates, watch_list):
matches = set()
for u in updates:
for w in watch_list:
if re.match(w, u):
matches.add(u)

return matches


label = os.environ.get("LABEL","")
message = "{0}<span color='{1}'>{2}</span>"
args = create_argparse()

updates = get_updates()
if args.aur:
updates += get_aur_yaourt_updates()
elif args.aur_yay:
updates += get_aur_yay_updates()

update_count = len(updates)
if update_count > 0:
if update_count == 1:
info = str(update_count) + ' update available'
short_info = str(update_count) + ' update'
else:
info = str(update_count) + ' updates available'
short_info = str(update_count) + ' updates'

matches = matching_updates(updates, args.watch)
if matches:
info += ' [{0}]'.format(', '.join(matches))
short_info += '*'
print(message.format(label, args.updates_available_color, info))
print(message.format(label, args.updates_available_color, short_info))
elif not args.quiet:
print(message.format(label, args.base_color, 'system up to date'))

保存更改并从文本编辑器中退出。

现在,使用以下命令将此文件设置为可执行:

1
sudo chmod +x ~/.config/scripts/arch-update

接下来,打开 i3blocks 配置文件:

1
nano ~/.config/i3blocks/i3blocks.conf

并将以下内容粘贴到所需的位置:

1
2
3
4
5
[arch-update]
command=/home/$USER/.config/scripts/arch-update
interval=3600
markup=pango
LABEL=

保存更改并重新加载 i3 窗口管理器,它将显示需要更新的软件包数量。

如果你正在使用 Ubuntu,你可以 按照 GitHub 页面上的说明 进行操作。

添加音量指示块

添加音量指示块需要一些努力,因为你希望它的行为符合预期。你需要实现以下功能:

  • 使用媒体控制键管理音量的键绑定
  • 添加一个指示音量的音量块

但要做到这一点,首先你需要安装一些依赖项。

如果你使用的是 Arch Linux,请使用以下命令:

1
sudo pacman -S pulseaudio-alsa pulseaudio-bluetooth pulseaudio-equalizer pulseaudio-jack alsa-utils playerctl

如果你使用的是 Ubuntu/Debian 系统,请使用以下命令:

1
sudo apt install pulseaudio-module-bluetooth pulseaudio-equalizer pulseaudio-module-jack alsa-utils playerctl

接下来,让我们看看如何在 i3 窗口管理器中启用媒体控制键。

首先,打开 i3 配置文件:

1
nano ~/.config/i3/config

转到文件的末尾,并粘贴以下内容:

1
2
3
4
5
# Key bindings for Media control keys
bindsym XF86AudioPlay exec playerctl play
bindsym XF86AudioPause exec playerctl pause
bindsym XF86AudioNext exec playerctl next
bindsym XF86AudioPrev exec playerctl previous

现在,让我们为此块创建一个新文件:

1
nano ~/.config/scripts/volume

然后粘贴以下内容:

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
#!/usr/bin/env bash
if [[ -z "$MIXER" ]] ; then
MIXER="default"
if command -v pulseaudio >/dev/null 2>&1 && pulseaudio --check ; then
# pulseaudio is running, but not all installations use "pulse"
if amixer -D pulse info >/dev/null 2>&1 ; then
MIXER="pulse"
fi
fi
[ -n "$(lsmod | grep jack)" ] && MIXER="jackplug"
MIXER="${2:-$MIXER}"
fi
if [[ -z "$SCONTROL" ]] ; then
SCONTROL="${BLOCK_INSTANCE:-$(amixer -D $MIXER scontrols |
sed -n "s/Simple mixer control '\([^']*\)',0/\1/p" |
head -n1
)}"
fi

# The first parameter sets the step to change the volume by (and units to display)
# This may be in in % or dB (eg. 5% or 3dB)
if [[ -z "$STEP" ]] ; then
STEP="${1:-5%}"
fi

NATURAL_MAPPING=${NATURAL_MAPPING:-0}
if [[ "$NATURAL_MAPPING" != "0" ]] ; then
AMIXER_PARAMS="-M"
fi

#------------------------------------------------------------------------

capability() { # Return "Capture" if the device is a capture device
amixer $AMIXER_PARAMS -D $MIXER get $SCONTROL |
sed -n "s/ Capabilities:.*cvolume.*/Capture/p"
}

volume() {
amixer $AMIXER_PARAMS -D $MIXER get $SCONTROL $(capability)
}

保存更改并退出配置文件。

接下来,打开 I3blocks 配置文件:

1
nano ~/.config/i3blocks/i3blocks.conf

然后粘贴以下内容:

1
2
3
4
5
6
7
8
9
10
[volume]
command=/home/$USER/.config/scripts/volume
LABEL=♪
#LABEL=VOL
interval=1
signal=10
#STEP=5%
MIXER=default
#SCONTROL=[determined automatically]
#NATURAL_MAPPING=0

保存更改并重新加载 i3,从现在开始,音量快捷键将起作用,并且指示器将按预期工作!

💡 如果遇到音频/视频不工作等问题,请使用此命令,它应该解决该问题:

1
systemctl --user disable --now pipewire.{socket,service} && systemctl --user mask pipewire.socket

添加 Spotify 块

我将使用 firatakandere 的脚本来添加此功能。在继续之前,你可以先查看一下该脚本。

首先,创建并打开一个用于 Spotify 块的新文件:

1
nano ~/.config/scripts/spotify.py

然后粘贴以下内容:

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
#!/usr/bin/python

import dbus
import os
import sys


try:
bus = dbus.SessionBus()
spotify = bus.get_object("org.mpris.MediaPlayer2.spotify", "/org/mpris/MediaPlayer2")


if os.environ.get('BLOCK_BUTTON'):
control_iface = dbus.Interface(spotify, 'org.mpris.MediaPlayer2.Player')
if (os.environ['BLOCK_BUTTON'] == '1'):
control_iface.Previous()
elif (os.environ['BLOCK_BUTTON'] == '2'):
control_iface.PlayPause()
elif (os.environ['BLOCK_BUTTON'] == '3'):
control_iface.Next()

spotify_iface = dbus.Interface(spotify, 'org.freedesktop.DBus.Properties')
props = spotify_iface.Get('org.mpris.MediaPlayer2.Player', 'Metadata')

if (sys.version_info > (3, 0)):
print(str(props['xesam:artist'][0]) + " - " + str(props['xesam:title']))
else:
print(props['xesam:artist'][0] + " - " + props['xesam:title']).encode('utf-8')
exit
except dbus.exceptions.DBusException:
exit

完成后,使用以下命令使其可执行:

1
sudo chmod +x ~/.config/scripts/spotify.py

现在,打开 I3blocks 配置文件:

1
nano ~/.config/i3blocks/i3blocks.conf

然后粘贴以下内容(建议将其粘贴到块的开头):

1
2
3
4
5
[spotify]
label=
command=/home/$USER/.config/scripts/spotify.py
color=#81b71a
interval=5

保存更改,退出配置文件,并重新启动 i3。

添加了我提到的块后,状态栏将如下所示:

在 i3 窗口管理器中定制 i3blocks

你可以查看我的主屏幕,其中包含这些块(点击下方的图片查看)。

在 i3 窗口管理器中定制 i3blocks

📋 如果你对那些默认块(文档和问候语)的位置感到困惑,我用了几个注释将它们禁用以实现所示的外观!

在 Linux 中使用 i3gaps

如果你想在窗口之间添加间隙,可以使用 i3gaps。在颜色方案之后,i3gaps 是这个指南中最关键的元素。

要使用间隙,你必须对 i3 配置文件进行一些更改。

打开 i3 配置文件:

1
nano ~/.config/i3/config

转到文件的末尾,并粘贴以下内容:

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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# default gaps
gaps inner 15
gaps outer 5

# gaps
set $mode_gaps Gaps: (o)uter, (i)nner, (h)orizontal, (v)ertical, (t)op, (r)ight, (b)ottom, (l)eft
set $mode_gaps_outer Outer Gaps: +|-|0 (local), Shift + +|-|0 (global)
set $mode_gaps_inner Inner Gaps: +|-|0 (local), Shift + +|-|0 (global)
set $mode_gaps_horiz Horizontal Gaps: +|-|0 (local), Shift + +|-|0 (global)
set $mode_gaps_verti Vertical Gaps: +|-|0 (local), Shift + +|-|0 (global)
set $mode_gaps_top Top Gaps: +|-|0 (local), Shift + +|-|0 (global)
set $mode_gaps_right Right Gaps: +|-|0 (local), Shift + +|-|0 (global)
set $mode_gaps_bottom Bottom Gaps: +|-|0 (local), Shift + +|-|0 (global)
set $mode_gaps_left Left Gaps: +|-|0 (local), Shift + +|-|0 (global)
bindsym $mod+Shift+g mode "$mode_gaps"

mode "$mode_gaps" {
bindsym o mode "$mode_gaps_outer"
bindsym i mode "$mode_gaps_inner"
bindsym h mode "$mode_gaps_horiz"
bindsym v mode "$mode_gaps_verti"
bindsym t mode "$mode_gaps_top"
bindsym r mode "$mode_gaps_right"
bindsym b mode "$mode_gaps_bottom"
bindsym l mode "$mode_gaps_left"
bindsym Return mode "$mode_gaps"
bindsym Escape mode "default"
}

mode "$mode_gaps_outer" {
bindsym plus gaps outer current plus 5
bindsym minus gaps outer current minus 5
bindsym 0 gaps outer current set 0

bindsym Shift+plus gaps outer all plus 5
bindsym Shift+minus gaps outer all minus 5
bindsym Shift+0 gaps outer all set 0

bindsym Return mode "$mode_gaps"
bindsym Escape mode "default"
}
mode "$mode_gaps_inner" {
bindsym plus gaps inner current plus 5
bindsym minus gaps inner current minus 5
bindsym 0 gaps inner current set 0

bindsym Shift+plus gaps inner all plus 5
bindsym Shift+minus gaps inner all minus 5
bindsym Shift+0 gaps inner all set 0

bindsym Return mode "$mode_gaps"
bindsym Escape mode "default"
}
mode "$mode_gaps_horiz" {
bindsym plus gaps horizontal current plus 5
bindsym minus gaps horizontal current minus 5
bindsym 0 gaps horizontal current set 0

bindsym Shift+plus gaps horizontal all plus 5
bindsym Shift+minus gaps horizontal all minus 5
bindsym Shift+0 gaps horizontal all set 0

bindsym Return mode "$mode_gaps"
bindsym Escape mode "default"
}
mode "$mode_gaps_verti" {
bindsym plus gaps vertical current plus 5
bindsym minus gaps vertical current minus 5
bindsym 0 gaps vertical current set 0

bindsym Shift+plus gaps vertical all plus 5
bindsym Shift+minus gaps vertical all minus 5
bindsym Shift+0 gaps vertical all set 0

bindsym Return mode "$mode_gaps"
bindsym Escape mode "default"
}
mode "$mode_gaps_top" {
bindsym plus gaps top current plus 5
bindsym minus gaps top current minus 5
bindsym 0 gaps top current set 0

bindsym Shift+plus gaps top all plus 5
bindsym Shift+minus gaps top all minus 5
bindsym Shift+0 gaps top all set 0

bindsym Return mode "$mode_gaps"
bindsym Escape mode "default"
}
mode "$mode_gaps_right" {
bindsym plus gaps right current plus 5
bindsym minus gaps right current minus 5
bindsym 0 gaps right current set 0

bindsym Shift+plus gaps right all plus 5
bindsym Shift+minus gaps right all minus 5
bindsym Shift+0 gaps right all set 0

bindsym Return mode "$mode_gaps"
bindsym Escape mode "default"
}
mode "$mode_gaps_bottom" {
bindsym plus gaps bottom current plus 5
bindsym minus gaps bottom current minus 5
bindsym 0 gaps bottom current set 0

bindsym Shift+plus gaps bottom all plus 5
bindsym Shift+minus gaps bottom all minus 5
bindsym Shift+0 gaps bottom all set 0

bindsym Return mode "$mode_gaps"
bindsym Escape mode "default"
}
mode "$mode_gaps_left" {
bindsym plus gaps left current plus 5
bindsym minus gaps left current minus 5
bindsym 0 gaps left current set 0

bindsym Shift+plus gaps left all plus 5
bindsym Shift+minus gaps left all minus 5
bindsym Shift+0 gaps left all set 0

bindsym Return mode "$mode_gaps"
bindsym Escape mode "default"
}

保存更改并退出配置文件。

使用 Mod + Shift + r 重新加载 i3,并会看到窗口之间的间隙:

在 i3 窗口管理器中使用 i3gaps

但是,如果你想调整间隙的大小怎么办?这非常简单,只需要简单的步骤即可完成:

  • 按下 Mod + Shift + g 进入间隙模式
  • 使用给定的选项选择要更改的内容
  • 使用 + 或 - 增加/减小间隙
  • 完成后,按 Esc 键退出间隙模式

就是这样!

我们忘记自定义终端了吗?

不用担心;你可以 切换到 Zsh,这是一个不同的 shell,使终端看起来与众不同,或者探索一些鲜为人知的 Linux Shell

无论如何,你都可以 自定义现有终端,或选择不同的 终端模拟器

我希望你不再畏难如何美化系统! 😎

如果你有任何建议或想展示你的配置,请在评论部分留言。

(题图:MJ/2874542d-6a8f-4b27-8e65-477389a0dcca)


via: https://itsfoss.com/i3-customization/

作者:Sagar Sharma 选题:lkxed 译者:ChatGPT 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

程序员的数学2-概率统计

前言

  • 概率是面积与体积的泛化
  • 随机变量是一种以变量为名的函数

Open Information Extraction: A Review of Baseline Techniques, Approaches, and Applications

开放域抽取综述

TeacherLM: Teaching to Fish Rather Than Giving the Fish, Language Modeling Likewise

Use “{Question} {Answer} {Fundamentals} {Chain of Thought} {Common Mistakes}” five-element training object for each sample. These sample to train a small model called TeacherLM to re-construct others training data to train or fine-tuning larger LLM

Improving Prompt Tuning with Learned Prompting Layers

选择性prefix-tuning learning 由原来全部加个prefix 到 现在的选择性添加 prefix

Woodpecker: Hallucination Correction for Multimodal Large Language Models

Woodpecker的架构如下,它包括五个主要步骤: 关键概念提取、问题构造、视觉知识检验、视觉断言生成 以及幻觉修正。

ChatKBQA: A Generate-then-Retrieve Framework for Knowledge Base Question Answering with Fine-tuned Large Language Models

微调大模型+知识图谱 code link

Controllable Text Generation via Probability Density Estimation in the Latent Space

  1. 这篇论文是想干啥的

    想要更好的进行基于给定属性的可控文本生成,想要实现更好的可控文本生成效果

  2. 为什么之前的方法效果不好原因在哪里?

    之前的方法 无法有效地建模具有多样属性、高维度和非对称结构的复杂空间, 隐空间是一个属性空间,需要在该空间中找到多属性最优点,但是这个空间是高纬度且非对称的,无法简单通过在两个单属性点之间找到多属性点,当我们在数学上尝试混合不同的属性时,有可能会超出这些属性原本存在的范围,从而导致生成的句子无法体现我们想要的特质

  3. 这篇文章提出了什么方法 使得效果更好了呢?

    之前的方法之所以效果不好,是因为要建模的属性隐空间是极其复杂的,导致建模效果很差,而本文提出一种解决思路就是将原本极其复杂的隐空间先转化为简单的可逆标准空间,然后便可以用很简单的方法在简洁的空间中找到要找的属性点,之后通过可逆操作将其映射到复杂的属性隐空间中便可以了

  4. 多属性隐空间 到 简单空间 ,简单空间再到多属性隐空间 这两个过程是怎么变换的?

  5. loss是怎么得到的?

How-to-retrieve-papers-XHU

目录

嗯,由于github的readme添加目录比较麻烦,所以这里就手动写个目录。Section 1是如何检索论文;Section 2是推荐阅读的论文与不推荐阅读的,其中包括如何检索论文分区(中科院JCR分区和CCF评级),期刊评级(CCF评级),以及中科院预警期刊;Section 3是关于我个人推荐的阅读论文的方式。

1 如何检索论文

1.1 SCI-HUB

有的论文不是免费获取的(比如 springer 旗下的会议或者期刊),这个时候就需要使用 doi 去搜索论文。在比如 Engineering village 上搜索论文,找到论文的 doi,然后百度 SCI-HUB (因为 SCI-HUB 的链接经常换,所以这里就不贴链接了),在 SCI-HUB 中搜索 doi 一般都能下载你想要的论文。

doi

scihub

1.2 dblp

dblp 算是我平时最喜欢用的搜文献的工具。

百度搜索dblp,第一个就是了。或者dblp网址:https://dblp.org/

在检索栏就可以进行检索,包括关键字文章名作者名期刊名会议名等等,都可以检索。

dblp-首页

在检索页中,其排序方式是按照年份进行排序的。可以看得到作者名论文名发表刊物。同时,在左侧会有颜色的标记,其中:

  1. 红色:期刊论文;
  2. 蓝色:会议论文;
  3. 灰色:未发表论文,比如arxiv,CoRR等;
  4. 黄色:书籍;
  5. 其余颜色查看:https://blog.csdn.net/DXY587542/article/details/114306545

dblp-检索页

至于在dblp上下载论文,把鼠标放置论文前这一坨上,选择electronic edition via DOI,如果论文可以免费下载,会有 (open access) 的字样。

dblp-下载论文

通过这个链接进入后,一般来说都可以下载论文,如果下载要钱,那么你可以在页面里面找到DOI,然后SCI-HUB,你懂我意思。(当然这个截图是个错误示范,IEEE Access尽管是个二区,但是是中科院预警期刊,就是属于那种审稿人看着你参考文献里面有个Access的论文估计都会看低你两眼的那种……食之无味,弃之可惜)。或者说你可以在dblp里面有没有相同的论文,只是说发表在arxiv或者CoRR里面的论文,那个就是免费下载的,就比如下图:

dblp-下载论文-2

dblp中还可以选择下载RIS,导入EndNote中做文献管理,但是 DBLP 中千万别下载会议论文的 RIS,因为 DBLP 上会议论文的 RIS 下载下来的类型是 Conference paper,而正常的会议论文类型为 Conference procedding,格式有问题,就会导致你导出论文引用时会有问题;也可以下载BibTex,从此不用再纠结于一个字一个字敲参考文献:

dblp-RIS与BibTex

1.3 arxiv

百度搜索arxiv,第一个就是。或者arxiv网址:https://arxiv.org/ 或者:https://arxiv.org/corr (后者就是计算机的了)

arxiv-检索

写了论文怕被审稿人嫖走了,就可以投稿在arxiv上宣告主权。

1.4 ReadPaper

ReadPaper 是沈向洋博士创办的一个论文社区,网址为:https://readpaper.com/。

ReadPaper 是国内的网站,所以检索速度很快,并且每篇论文你都可以直观的看到分区CCF 评分是否有PDF引用量等。同时,ReadPaper 每篇论文都有个讨论社区,能够讨论论文中的一些问题。关于 ReadPaper 的详细介绍可以看我之前写的一篇评测博客:https://blog.csdn.net/qq_35357274/article/details/126627945。

ReadPaper

1.5 Papers with code

百度搜索Paperswithcode,第一个就是,或者Paperswithcode网址:https://paperswithcode.com/

这里面可以搜索到想要的论文,以及其在github上公开的代码:

paperswithcode

2 论文哪些可读,哪些不可读?

最直白的查看论文可不可读的方法,就是搜索论文的分区。这里推荐的期刊查询的是letpub,网址在这里:https://www.letpub.com.cn/ (虽然该网站广告就像小网站一样,但是确实不错)

进入页面后,选择智库资源中的最新SCI期刊信息查询系统

letpub-首页

输入要检索的期刊,就可以查看到简略信息,也可以点击进入查看详细信息:

letpub-检索页

其中有两个分区信息,第一个是美国那边的评级(没啥参考价值):

letpub-分区一

第二个就是中科院的JCR分区:

letpub-分区二

当然,上面还可以看到论文审稿速度啊巴拉巴拉的,可以自行探索。

这里推荐的呢,对于期刊论文,就是中科院分区一区二区的论文。当然,对于有些学校申请博士可能看的是CCF上的内容,这个的搜索方式就是上CCF官网进行检索:https://www.ccf.org.cn/ ,网站上最新版的CCF推荐的国际期刊和会议的网址如下:https://www.ccf.org.cn/Focus/2019-04-25/663625.shtml

同样,还有中科院预警期刊。这个就百度中科院预警期刊即可查看到预警期刊,比如20年底发布的:https://www.zhihu.com/question/437284270

最后呢,就是经验之谈啦,因为我的了解的面不够,所以我这里就谈谈我自己觉得可以的和不可以的:

  1. 可以的:AAAI,ACL,EMNLP,SIGIR,NLPCC,KBS,information science,neurocomputing,ICLR,IEEE trans…
  2. 不行的:再次鞭尸IEEE Access,食之无味,弃之可惜。

3 如何阅读论文?

对于一个做科研的人来说,读论文就像是吃饭喝水一样,是每个科研人都绕不开的坎,所以这里我就分享下我这两年读论文的经验。

3.1 前期工作

实际上做科研这件事情,是一件需要赶时间的工作,也许你想到了一个点,但是你做的比别人慢了,你刚收笔,就发现别人论文发出来了,都是很正常的一件事。但是在这种情况下,就更不应该一来就上手读论文,而是应该先做前期准备工作,正所谓工欲善其事,必先利其器。以下是我觉得应该花 3 - 6 个月做的工作:

3.1.1 数学

数学永远是工科生绕不开的一个坎,以我们实验室的研究方向来说,如果你做社会网络,矩阵你得会吧,概率论你得会吧,图论你得会吧;如果你做深度学习,那你天天看的都是 $y=\sigma(Wx+b)$。那么数学应该看什么?应该怎么看?

其实数学这东西,你过段时间没看也就忘了,这些都不是关键,最重要的是,当你看论文,看到某个数学符号,你得知道这个符号是什么,然后再去回忆或者百度。同时我们工科生对于数学而言不是说要会做题,那些都是交给计算机去做的,我们要的只是知道这个是什么,怎么用就行了,就比如矩阵你只用知道是一种映射关系就好。

  • 线性代数:或者叫矩阵论也行,这是怎么都绕不开的东西,无论是论文里面的公式,还是你写的代码,都是矩阵(用矩阵写代码能够有效提高代码的并行计算效率)。当然,你用的同济大学线性代数教材可以丢了,用来擦屁股都嫌纸硬的,考研的东西也没必要,就是八股文。线代我最推荐的是 3Blue1Brown 的课程,打开你新世界的大门。链接:【【官方双语/合集】线性代数的本质 - 系列合集】 https://www.bilibili.com/video/BV1ys411472E?share_source=copy_web&vd_source=be19fd8057d8c92fcca5f91666f9b006 。不过这个是初级课程,里面没有涉及到 这些内容,要中高级的内容,可以看 《程序员的数学》
  • 概率论:概率论和矩阵论一样,都是随时用到的东西。比如经典的 PageRank 或者 传染病模型 都是随机游走模型。概率论实际上浙江大学版的概率论就很可以的,不过还是比较晦涩,全是公式,要简明版的,也可以看 《程序员的数学》

数学的话,差不多就要花费3个月左右的时间,先看数学能够有效提升你论文公式阅读的速度(虽然你论文看多了就会发现公式都是大同小异的,尤其是深度学习),同时你还能够在以后写论文的时候提升你自圆其说的能力。

3.1.2 代码

如果说数学是你看懂论文的基础,那么代码就是你实现论文的地基。你有再多的想法,不会写代码一样白搭。代码的话,用 Python 就够了,不过在 Python 的基础上,还有你要看的东西。

  • Python:如果你没学过 Python,先去 Github 上搜一下 Python 的编程风格,每学一个语言先学这个语言的编程风格是个好习惯,这个差不多半天看得完。Python 的语法与自然语言很像,所以学起来很快,如果你有编程基础,并且也做过许多项目,那么看 Python 半天就够了,就看看 ifforwhile 语句,再看看 Python 中最重要的三个数据结构 元组 (tuple)列表 (list)字典 (dict),最后看看文件操作,差不多半天时间可以搞定(当然有空可以看看魔术方法,很酷炫,但是你不会也不影响,因为我也不会)。如果你一点代码基础都没有(别骗自己,没有就是没有),那么最多一个月也怎么都学得会。
  • AnacondaAnaconda 是用于 Python 的环境管理,简单来说你一个项目是用 python 2 写的,下一个项目你要用 python 3,如果在电脑上又装 python 2,又装 python 3,可能会有冲突。Anaconda 就是用来管理环境的,比如有的环境用来管理 python 2,有的环境用来管理 python 3,有的用来管理 django,有的用来管理 torch。这个很简单,但是很重要,如果你不会 anaconda,哪天把师兄师姐服务器环境搞炸了我估计他会一波带走你的。具体的配置可以看我以前的博客:https://blog.csdn.net/qq_35357274/article/details/118582625 。这个也差不多半天可以搞定。
  • Pytorch:如果你不选择用深度学习,那么这个你可以跳过。如果你选择用深度学习,那么这里我强烈建议用 torch。根据 22 年 6 月发表的报告,工业界 80% 的企业已经放弃使用 Tensorflow 改用 torch 了,就足以见得现在 Tensorflow 有多垃圾。Torch 一定要在你学会 python 的基础上再学,别想着一口能吃成胖子。同时你也一定要先学完 torch 后再去看别人的代码,不然你会一直在一些弱智问题上纠结浪费自己的时间,这样反而才是效率最低下的做法。Torch 的话推荐看 Dive-into-Deeplearning 这本电子书,链接为:https://tangshusen.me/Dive-into-DL-PyTorch/#/ (不过这个链接经常打不开,不知道怎么回事)。Torch 要学差不多 20 - 40 天。注:这个时间是必须先花的,别想着省!!!如果你连 forward 在什么时候会被调用都不知道,那你是怎么敢省这个时间的?
  • numpy, scikit 等其他库:这些库不需要专门的学习,因为经常会用得上,所以遇到的时候再百度再学就够用了。

简而言之,代码这一块最需要花时间的还是在框架上,其余的都是遇到的时候再百度都来得及。代码不用纠结于你写的好不好看,是不是一个完整的程序,能跑通就行了,毕竟刚刚也说了,发论文就是个争分夺秒的事情,如果你太过于纠结写得好不好看反而是舍本逐末的事情。同时,学习代码的时候一定要学会看官方文档和看源码,像 torchtransformers 这些库的文档和源码比网上搜的博客清晰的多。

3.2 一篇论文该怎么读?

许多人,包括我,在最开始看论文的时候,都是从头到尾一句话一句话的翻译,这个也没错,但是这样反而会效率不高。我这里就从科研的读论文的顺序和读论文该用什么方式来写。

3.2.1 科研阶段读论文顺序

对于刚开始做科研的同学,最大的困惑就是不知道该读什么论文。通常都是导师丢一啪啦论文下来,或者直接找师兄师姐要一啪啦论文下来看,但是实际上这样我个人觉得是有问题的,因为很多论文,尤其是会议论文,都是建立在你是从事了这个行业一段时间的,如果你上来就硬看,可能看完一篇论文最大的收获就是学会了几个专有名词。这里关于论文的阅读顺序我整理如下:

  • 初学者先问清导师团队的研究方向有哪些,然后搜相关的综述论文(一定要搜最新的那一篇,因为这一篇里面肯定会引用老的综述论文)。对于看论文还不熟练的同学可能看英语会很吃力,看专业名词看的头痛,很多百度都还百度不到的。这也没事,可以搜近两年这个方向清北的博士毕业论文来看,他们的毕业论文可以只用关注于第二章,即国内外研究现状,这一部分就是一篇顶级的中文综述,先了解下这个方向有哪些方法,然后再看看相关的基础知识。就比如你做自然语言处理的话,词嵌入你得知道吧,传统方法里面最经典的 Word2Vec 得知道吧,这两年最热门的 transformer 得知道吧。
  • 当有了方向的直观认识后,一定要尽快确定自己的研究方向,不然开题前换方向的话等于你之前的工作都白做了。这个阶段我推荐最多研一上期结束的时候就要确定。当确定了方向后,就去看看这个领域经典的论文,比如自然语言处理里面的 Word2VecGloVeTransformerBERT 这些。
  • 当上述的工作做完后,就可以开始看实际的论文了,这个阶段我推荐先从一区的论文开始看,一区以下的论文不太推荐,二区以下的碰都别碰,当然,二区的 IEEE ACCESS 也要避坑。这个时候你可能正好研一上期快结束了,但是实际上基础还是处于相对薄弱的阶段,所以这个时候看 SCI 是个很好的过程。SCI 写的会很详细,有的时候你都会看到一句话翻来覆去写个几遍的。同时 SCI 会将模型的每个模块写的很详细,比如每篇跟 LSTM 相关的论文,一定会有一套 LSTM 相关的公式,这个阶段可以做到查漏补缺,不仅可以锻炼阅读论文的能力,也可以补充一下自己的基础知识。不过我个人不建议太过于纠结期刊论文的思想,因为一般也没有什么思想。
  • 当看了一两个月的一区论文后,就可以进入到最后一个阶段了。这个阶段就只读顶会论文(除非你的研究方向只有 SCI,像我的研究方向顶会就只有个位数)。为什么说只读顶会论文,我这里借用 MIT AI LAB 他们的师兄给师弟师妹写的原话:你几乎无法在期刊论文里面找到任何有新意的东西。当然这句话是有局限性的,因为我发现这句话仅适用于部分计算机的领域,当然,人工智能属于这句话的范畴。实际上你仔细想一下自己领域所有著名的模型、方法,你会发现好像一篇出自期刊的论文都找不出来(nature science 不算)。我看过许多顶会论文,坦白的说,就算是 CCF-C 的会议论文的创新性,都能碾压大多数一区的论文了,虽然这些论文方法可能很简单。这类论文会很有趣,但是也会很晦涩。因为会议论文会有篇幅限制,所以大家都是能不写的东西就不写,比如你写期刊论文的时候,写 BERT 都可以写个四五页的,但是你写会议论文的时候,一句话加一个公式 $h = {\rm BERT}(x)$ 就结束了。所以对于基础不好的同学在看会议论文的时候会很煎熬,因为你没有扎实的知识储备。
  • 当你会议论文看的最够多了后,就会有许多创意了。实际上如果你只看当年会议里最热门的话题(比如 18 年的 BERTGNN;20 年的对比学习;21 年的提示学习),随便改一改,都是篇一区论文的质量了,所以我一直说发论文有手就行
  • 在这中间还有一个很重要的过程,就是学术报告,包括但不限于实验室的组会。
    • 对于实验室的组会来说,这是个很好的阶段,能够让你在一小时内简单了解一篇论文,然后看你有没有需要,如果有需要,就找那个同学要原文来看。
    • 还有就是一定一定一定要多参加国内外的会议,就算是国内的,不在 CCF 表上的会议(虽然我一直都认为 CCKS 要升 CCF-C 了,所以现在发个 CCKS 我觉得会很赚),都会请到许多行业大佬(比如你可以随时随地看到刘知远和黄明烈两个老师的名字)来做汇报,这些汇报就是他们最新的研究成果,并且由论文作者直接分享,比你自己去咬文嚼字看论文效果要好得多。同时在会议上老师们还会给你提供许多他们认为未来的可研究话题,这些对自己的选题都能有很好的帮助。
    • 同时可以 B 站上关注一下 ReadPaper论文阅读,这里会不定期的请许多论文一作来分享他们的工作,所以也可以快速阅读一篇论文的思想。

3.2.2 看论文该怎么看?

我看过许多师弟师妹看论文都是一句话一句话的看,有的还是翻译成中文打印下来看,更有甚者不仅要一句话一句话翻译,还要用笔去一句话一句话抄……亚雷吗,是硕士三年太长了么……

麻了

首先这是个最大的误区,就是你论文一句话一句话的看。还是引用 MIT AI LAB 的话:你不可能写论文的时候每一句都写的很完美。那么同理,不是每一句话都是有必要去阅读的。

首先,一定要看英文原文!一定要看英文原文!一定要看英文原文! 这个有两个原因:

  • 如果你看博客,假设搜的到的话,这个是别人 N 次咀嚼后的结果,可能第一个看论文的人看完后,得出错误的结论,第二个人看了这个错误的结论,然后以讹传讹下来,你看的博客不知道错了多少。
  • 如果你全文翻译,有的句子翻译出来都不是原文表达的意思了,比如你输入一个长难句进翻译软件你看出来会不会有问题。

其次,阅读论文要分为 略读精读。同时,看论文的顺序也不应该是自顶而下的看,根据我观察的来自 新加坡国立电子科大西南交大国家重点实验室贝壳找房 等诸位大佬的论文阅读习惯,再结合上我看论文的习惯而言,我将看论文的顺序总结为:摘要总结模型图实验结果的表和图引言其他

  • 当你开始看一篇论文时,不能够确定这篇论文要精读还是要略读,所以就按照我之前总结的顺序来阅读。如果你确定这篇论文你是要精读的,那么就可以直接自顶而下阅读(不过对于没经验的人来说,很难能够确定论文是不是要精度的,所以没经验之前最好按照我给的顺序来阅读)。
  • 通常看完摘要,看完总结,看完模型图后,你就能大概把握这篇论文是不是要略读了。最简单的判断办法就是你看模型图是不是 叠层数 或者 缝合怪,叠层数就是比如 LSTM 上加了个 ATT,缝合怪就是比如 LSTM + CNN。如果是这样的,那么稍稍看看实验结果就行了(这类论文的实验结果一般也是编的,一个敢编,一个敢收),然后这篇论文就到此为止了。
  • 当你判断这篇论文不是属于略读的范畴的时候,那么就是精读。精读的话可以选择我刚刚的那个顺序来读,也可以选择从头开始读,核心目的就是看懂这篇论文。

当然,在阅读论文的时候,也不是要每一句话都读。通常一篇优秀的论文都是 总-分-总 结构,在看的过程中,你可以跳着看,比如每一段只看第一句,看下他这段话的中心思想是什么。同时,在遇到很多公式的时候(我相信大部分人都被这个难到了),实际上你只需要推导一两篇论文的公式,大部分论文的公式都是大同小异的,之后遇到都可以跳过了。比如我就从来不会看 LSTM 的公式,那一大坨我会直接跳过 (除非他这篇论文就是改进的 LSTM)。同时,一篇优秀的论文,你不看文字介绍,你只看图表以及它们的标题都可以看懂这个图表的内容,所以关于图表介绍的那一大坨文字也可以选择性跳过。

3.2.3 看论文主要看什么?

这里我就引用一下沈向洋博士和华刚博士提出的 论文十问

  • ** 论文试图解决什么问题?
  • 这是否是一个新的问题?
  • * 这篇文章要验证一个什么科学假设?
  • 有哪些相关研究?如何归类?谁是这一课题在领域内值得关注的研究员?
  • * 论文中提到的解决方案之关键是什么?
  • * 论文中的实验是如何设计的?
  • * 用于定量评估的数据集是什么?代码有没有开源?
  • * 论文中的实验及结果有没有很好地支持需要验证的科学假设?
  • * 这篇论文到底有什么贡献?
  • 下一步呢?有什么工作可以继续深入?

* 代表了我认为最重要的问题。

看论文我认为首先要看的是这篇论文的 motivation。每篇论文的模型,实验全是围绕着这个 motivation 而展开的。motivation 会出没在 introduction 中。通常 introduction 里面第一段是背景介绍(一般是废话,当然看作者水平),第二段或者第三段会提出一个问题(这里通常会有例子,包括但不限于文字、图、表),再下一段会说明为了解决这个问题,他们怎么怎么做的,而这个问题与解决方案就是这篇论文的 motivation,抓住了这个 motivation 才能准确把握住作者后面写的东西。

当知道作者的 motivation 后,可以看下模型图中,他们提出了什么新的模块,来解决他们发现的问题,这也就是对应了 论文中提到的解决方案之关键是什么? 通常一篇好的论文,你可以直接从 motivation模型框架图 知道这篇论文 80% 的内容。

接着就是实验部分,你得分析下作者用了什么实验来验证他们的解决思路。实验通常会有几个板块,一个主试验(即对比实验),和别人的模型对比,看下自己创新的模块是否带来了提升。如果性能上的提升只有一点点,那么你就得开始怀疑究竟是这个数据集太难了,还是说这个模型本身就不能够解决这个问题,只是某一组跑出来的效果好了那么一点点。通常还得有一个消融实验,将模型创新的部分给删掉,看下性能上会损失多少,以此来说明这个模块是对模型性能有帮助的。这也就是 论文中的实验是如何设计的? 当你论文看得多了,自然也就知道自己该做什么实验了。

3.2.4 论文的实验要不要复现?

这个问题我秉持着怀疑的态度,我在这个问题上没有很好的方法论,因为我也没怎么复现过别人的实验。从我个人的角度上讲,我是特别不想复现别人的实验的,因为你会发现很多论文是不公布代码的;或者只公布一点点代码;或者关键代码不公布;或者公布出来你跑出来实验结果差了很多;或者你照着他的模型、参数给跑一遍,然后发现连基线模型都比不过。都是有可能的。

所以在这个问题上,我只会选择看他们模型的代码(即 models 文件夹下的内容),然后我只跑通这一个模块的内容。我不会选择去把他们的实验给实现,因为这个过程是个很费时费力的过程,而且有可能还跑不通。由于我用别人的模型的时候,一般都是放在新数据集上运行(如果你是在这篇论文的数据集上做实验,那么一般就是直接用别人论文里面的结果,不用自己跑),所以我只用关注于把别人的 model 给运行正常即可。

3.2.5 看论文方法流

自问自答式读论文,自己提出一个问题,自己从论文或者各种渠道去找到答案,然后再更根据上一个问题的答案再提出另一个问题,直到没有问题可以提问,注意提问题时应该以一个纯小白的角度提出问题,而且通常的第一个问题是这篇论文想干什么,也就是motivation

以下内容假定你的设备在同一局域网下,如果不在,你可以通过Tailscale组建虚拟网络

传输文件

不管以什么为服务端,都可以实现双向互传文件。

以电脑为服务端

如果有Python,可以在文件夹内运行命令python -m http.server,其他设备浏览器输入电脑IP地址的8000端口即可访问,适合少量大文件的分发。

SMB文件共享:参阅Windows 文件共享一节的内容(内网无需安装Tailscale),手机可以安装猫头鹰文件查看/下载。

Windows就近共享:在手机上安装NearShare或者AndDrop

macOS隔空投送:安卓手机可以安装AndDrop

ToDesk、向日葵具有传输文件的功能,QQ也有直接查看电脑文件的功能,但升级后砍了。

以手机为服务端

系统自带文件管理/互传APP:一般具有FTP/HTTP文件管理服务。

文件闪传:通过网页管理手机文件。

简朴:浏览器管理手机文件。

猫头鹰文件:可访问FTP/SFTP/WebDAV/SMB服务器,也可以自建SMB服务器。

Tailscale:右键,选设备,发送!参阅传送文件一节的内容。

对等传输

KDE Connect:文件、链接、键鼠。

LocalSend:全平台文件传输工具。

大道至简

在设备终端命令行内安装OpenSSH(手机在Termux内操作,需要执行termux-setup-storage命令),然后用scp命令完成这一切吧。

屏幕投影

电脑

VLC:选择“媒体>流>捕获模式>桌面”,随后可以将画面串流成多种协议的内容。

AirDroid Cast 网页版:通过浏览器的能力捕获画面,无线投屏到其他设备。

安卓手机

ScreenStream:安卓设备投屏到网页。

文件闪传也附带投屏功能。

终端共享Shell会话

使用screen开启共享会话,其他设备ssh连接上后执行screen -x即可共享输出。

也可以使用gotty、tty-share等工具将shell会话投影到网页上。

远程控制

电脑

微软自带的远程桌面:家庭版不可使用(可以用SuperRDP2解锁),使用时电脑会锁定。

第三方商业软件:Todesk(内存泄漏)、向日葵远程控制(轻度广告)、RayLink。

Moonlight:电脑端需要有Sunshine/NVIDIA SHIELD服务,可参考这篇博文

spacedesk:作为电脑的扩展屏使用。

手机

系统自带家人关怀远程协助应用:如果有的话。

RustDesk:全平台互相控制。

AnLink:操作手机、播放手机音频、传输文件。

Scrcpy/QtScrcpy:基于USB调试/无限调试特性操作手机,前者需要安装配置Android Platform Tools(ADB)环境,为命令行程序,后者已集成好环境,具有图形化界面,还支持播放设备音频。

大道至简

你需要OpenSSH。

生成SSH密钥

ED225519类型的密钥综合性能更好。

1
ssh-keygen -t ed25519 -C "内容"

生成好的密钥可以通过cat ~/.ssh/id_ed25519.pub查看。

将公钥加入认证列表

如果服务端是Windows OpenSSH,请将服务端%ProgramData%\ssh\sshd_config文件中的此行取消注释:

1
# PubkeyAuthentication yes

~/.ssh/authorized_keys文件中逐行添加公钥即可。

示例:我的SSH公钥

前言

在我曾经的文章中,我提到我的 Archlinux 系统已经连续使用两年了,期间一直没有出现过什么大问题。然我事实上我对这个系统安装一直有些不满意:

首先是不满意磁盘分区,我当时只给根目录分了 30G 空间,并且 /var 目录没有单独挂载分区,导致根目录的使用空间一直都挺捉襟见肘的,/home 目录也只分了 100G 空间,后期也不太够用。那可能会有人问,500G 的硬盘剩下的三百多 G 那里去了?其实剩下的空间又被我单独挂载在了 /home/$USER/data 目录下,用来放一些不常用的大文件。现在想一想这个分区方式是真的不太好。

其次是磁盘分区使用的文件系统是「good old」的 ext4 文件系统,虽然 ext4 使用起来很可靠稳定,但在特性上多少有些无聊,我想尝试一下新的文件系统 Btrfs,支持写时复制(CoW)、快照以及压缩等高级特性。

秉承着「没有坏就不要动它」的原则,虽然对系统安装有些不满意,但又不是不能用,也就这么用下来了。然而就在前些日子某次系统更新后,我突然发现鼠标不能用了,直到最后我发现其实是 keyd 的一个 bug,不知是否是奥米克戎后遗症导致我注意力变差,还是因为前一天晚上睡眠不足,我排查了好一会也没有找到故障原因,最后脑袋一热,决定重装系统。


由于 Arch linux 官方有着十分详尽的 wiki,同时 ArchlinuxCN 社区也维护了一版中文 wiki,国内外互联网上也有很多安装与配置教程,只要善用搜索引擎,安装 Archlinux 不是什么难事,所以本文为了篇幅考虑,不会将所有安装步骤列出来,只记录下我个人安装过程中遇到的需要注意的一些特殊配置,权当是个备忘录吧。

重装前的备份

因为我打算使用 btrfs 文件系统,虽然将 ext4 文件系统转换为 btrfs 文件系统是可行的,但是毕竟存在风险,保险起见还是备份数据,然后全盘格式化。

首先运行 pacman -Qe,这个命令可以列出系统中所有手动指定安装的包,运行 pacman -Qe >> list.txt 可以将这个软件包名单保存到 list.txt 文件里面,再将这个文件保存到方便查看的地方,比如自己的手机里什么的,方便重装后参照这个名单将软件装回来。

之后是备份整个家目录,以便重装完后恢复绝大多数的个人数据。我找到一个闲置的空的移动硬盘,不是空的也没关系,只要剩余空间够放下家目录的内容就行,将其挂载在 /mnt 目录下,并新建一个空文件夹 backup。为了在恢复数据时保留所有文件的权限,我使用 rsync 命令:

1
sudo rsync -avrh --progress /home/ /mnt/backup/

这个命令会将所有家目录中的文件同步至 /mnt/backup/ 路径下。选项 -avrh 可以在复制时保留文件的权限,/home/ 是需要备份的目录,/mnt/backup/ 是备份的目标目录,一定要注意路径最后的斜杠,路径最后是否有斜杠对于 rsync 命令来说是完全不同的两个路径,这里在路径最后加上了斜杠,之后再用 rsync 恢复数据时也需要在路径后面加上斜杠。备份数据可能需要较长时间,取决于硬盘的速度,备份完成后,再次检查一下数据备份是否出错,之后便可以着手重装系统了。

若你在根分区也有想要备份的文件,也可以选择备份。

系统安装

Archlinux 官方的系统镜像如今已经默认集成了一个十分好用的安装脚本,配置好网络后只需运行 archinstall 便可快速安装,不过需要注意的是,运行 archinstall 时会首先刷新镜像列表,如果网络不太好的话可能会花很长时间,所以在这之前可以手动编辑 /etc/pacman.d/mirrorlist 将国内镜像列表移动到最顶部,通过 head 命令查看文件的前 20 行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ head -n 20 /etc/pacman.d/mirrorlist
##
## Arch Linux repository mirrorlist
## Generated on 2023-02-26
##
## China
Server = https://mirrors.bfsu.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.aliyun.com/archlinux/$repo/os/$arch
Server = https://mirrors.cqu.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.hit.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.neusoft.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.nju.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.njupt.edu.cn/archlinux/$repo/os/$arch
Server = https://mirror.redrock.team/archlinux/$repo/os/$arch
Server = https://mirrors.shanghaitech.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.sjtug.sjtu.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.wsyu.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.xjtu.edu.cn/archlinux/$repo/os/$arch

或者直接在文件最开头手动添加国内镜像源,以北外镜像站为例,在文件最开头添加这样一行:

1
Server = https://mirrors.bfsu.edu.cn/archlinux/$repo/os/$arch

这样就可以跳过刷新镜像列表这一步,可以节省不少时间。

官方的安装脚本其实已经挺好用了,如果没什么特殊需求的话完全可以使用这个脚本非常快地安装一个新系统,但是我恰恰是有特殊需求的那种人。我打算配置系统休眠(Hibernation),需要一个 swap 空间,而官方安装脚本默认使用 zram 作为 swap,因为 zram 是将一部分内存空间压缩当作 swap 空间,而内存断电丢失数据的特性决定了它不可以用于系统休眠,想要配置硬盘上的 swap 需要手动分区,而安装脚本的手动分区功能我研究了半天也没搞明白怎么用,所以我最终决定抛弃安装脚本,手动安装。

手动安装系统的话基本上参照官方的安装教程就差不多了,以下是我个人的一些配置。

硬盘分区

我的硬盘分区挂载状态如下,运行 lsblk

1
2
3
4
5
6
7
8
9
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 465.8G 0 disk
├─sda1 8:1 0 512M 0 part /boot
├─sda2 8:2 0 16G 0 part [SWAP]
└─sda3 8:3 0 449.3G 0 part /home
/var/log
/var/cache/pacman/pkg
/

你会发现除了常规的 boot 分区 sda1 和 swap 分区 sda2 外,sda3 竟然被挂载到了四个目录下,这对于 btrfs 分区是可行的,btrfs 分区可以创建很多子卷(subvolume),每个子卷又可以像单独的分区一样被挂载,而且每个子卷又像文件夹一样可以共享这个分区所有的容量,挂载子卷而不是挂载分区,就不会出现一个分区用完了,而另一个分区还没用多少的尴尬情况。如果你真的想要限制子卷可使用的空间,也可以使用 Quota,不过这个功能目前并不稳定,请谨慎使用。btrfs 分区也可以像传统分区那样直接挂载整个分区,但这样情况下就不可以用快照功能了,所以并不推荐。

我使用的是 gdisk 来进行硬盘分区,你也可以使用其他的分区工具。对于支持 UEFI 的机器,/boot/boot/EFI 目录必须挂载到单独的 FAT32 分区,一般 boot 分区只需要几百兆大小。swap 可以为单独的分区或者是交换文件,一般而言使用交换文件配置要更为灵活,但是在 btrfs 分区上使用交换文件需要一些额外设置,而且休眠到交换文件也需要额外设置,所以为了方便起见,我直接划分了一个交换分区,至于交换空间的大小,若是想要休眠到硬盘,一般而言需要交换空间不小于机器物理内存的容量,对于小内存的机器,最好是两倍物理内存的容量,若是机器内存比较大,交换空间小于物理内存容量也是可行的,只是需要一些额外设置,我的电脑只有 8G 内存,保险起见我直接分了 16G 交换分区。剩余的空间我全给了主分区,将来格式化成 btrfs 文件系统。

接下来是格式化分区,分区设备名称不同的机器可能会不同,请自行修改:

1
2
3
mkfs.fat -F 32 /dev/sda1    # 格式化 boot 分区
mkswap /dev/sda2 # 格式化 swap 分区
mkfs.btrfs /dev/sda3 # 格式化主分区

然后是挂载分区,btrfs 分区的挂载比较复杂,首先挂载整个 btrfs 分区到 /mnt,这样才可以创建子卷:

1
2
3
4
5
6
7
mount /dev/sda3 /mnt    # 挂载分区
# 创建子卷
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@pkg
umount /dev/sda3 # 卸载分区

关于子卷的划分,我打算使用 Timeshift 来管理快照,而 Timeshift 只支持 Ubuntu 类型的子卷布局,也就是根目录挂载在 @ 子卷上,/home 目录挂载在 @home 子卷上;另外我还打算使用 grub-btrfs 来为快照自动创建 grub 目录,grub-btrfs 要求 /var/log 挂载在单独的子卷上;还有 @pkg 子卷挂载在 /var/cache/pacman/pkg 目录下,这个目录下保存的是下载的软件包缓存,也没什么保存快照的必要,所以也单独划分了个子卷。

接下来就是挂载子卷了,使用 subvol 挂载选项来指定挂载的子卷:

1
2
3
4
5
6
7
8
9
10
11
# 挂载根目录
mount /dev/sda3 /mnt -o subvol=@,noatime,discard=async,compress=zstd
# 挂载家目录
mkdir /mnt/home
mount /dev/sda3 /mnt/home -o subvol=@home,noatime,discard=async,compress=zstd
# 挂载 /var/log 目录
mkdir -p /mnt/var/log
mount /dev/sda3 /mnt/var/log -o subvol=@log,noatime,discard=async,compress=zstd
# 挂载 /var/cache/pacman/pkg 目录
mkdir -p /mnt/var/cache/pacman/pkg
mount /dev/sda3 /mnt/var/cache/pacman/pkg -o subvol=@pkg,noatime,discard=async,compress=zstd

除了 subvol 选项用来指定挂载的子卷,我还添加了其他的挂载选项用于优化 btrfs 文件系统的性能:noatime 选项可以降低数据读取和写入的访问时间;discard=async 选项可以在闲时释放磁盘中未使用的区块,也就是 TRIM,另外也可以不添加这个选项,而是在系统安装完成后启用 fstrim.timer 服务从而定时执行 TRIM,可以根据自己的喜好选择;compress 选项可以在数据写入前进行压缩,减少磁盘的写入量,增加磁盘寿命,在某些场景下还能优化一些性能,支持的压缩算法有 zliblzozstdzstd 算法是最快的。关于更多的挂载选项,可以看这里。在系统安装完成后也可以编辑 /etc/fstab 文件修改挂载选项。

因为 /var/log/var/cache/pacman/pkg 在将来并不会被保存快照,也可以选择为这两个目录禁用写时复制:

1
2
chattr +C /mnt/var/log
chattr +C /mnt/var/cache/pacman/pkg

接下来挂载其他分区:

1
2
3
4
5
# 挂载 boot 分区
mkdir /mnt/boot
mount /dev/sda1 /mnt/boot
# 启用 swap 分区
swapon /dev/sda2

接下来便可以继续接下来的安装步骤了。

安装过程

管理 btrfs 文件系统,比较推荐安装 btrfs-progs,其包含了很多用于管理 btrfs 文件系统的命令,前文用到的 btrfs subvolume create 命令就是来自这个软件包,Arch 官方的的安装镜像已经集成了这个软件包。可以在 pacstrap 步骤中安装这个包,我一般会在这个步骤装上如下的软件包:

1
pacstrap -K /mnt base base-devel linux-lts linux-lts-headers linux-firmware neovim btrfs-progs amd-ucode

base 和 base-devel 是系统核心的软件包组,linux-lts 和 linux-lts-headers 是长期支持版本的内核及其头文件,若是不追求较新的内核特性及驱动支持,长期支持版本内核更为稳定,linux-firmware 是各种常用的驱动,neovim 是一个文本编辑器,amd-ucode 是用于 AMD 处理器的微码文件,若是 Intel 处理器,可以安装 intel-ucode。

chroot 进入新系统后,除了官方推荐的配置,对于 btrfs 文件系统,需要编辑 mkinitcpio 文件,通常位于 /etc/mkinitcpio.conf,找到 MODULES=() 一行,在括号中添加 btrfs,这是为了在系统启动时提前加载 btrfs 内核模块,从而正常启动系统。记得每次编辑完 mkinitcpio 文件后都需要手动重新生成 initramfs:

1
mkinitcpio -P

配置完成后,再进行安装 GRUB

1
2
3
pacman -S grub
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=Arch
grub-mkconfig -o /boot/grub/grub.cfg

添加新用户:

1
useradd -m -G wheel -s /bin/bash user

这个命令添加了一个用户组为 wheel,shell 为 bash,用户名为 user 的新用户,如果之后打算恢复以前的家目录,建议使用和之前系统一样的用户名。

之后运行 visudo,如果环境变量没有指定默认编辑器,会提示选择,选择一个之后会进入文件编辑界面,找到 # %wheel ALL=(ALL:ALL) 一行,删除最前面的井号注释,这样所有在 wheel 用户组的用户都可以使用 sudo 命令了,或者要是不想每次运行 sudo 都要输入密码,可以取消注释 %wheel ALL=(ALL:ALL) NOPASSWD: ALL 这一行,但这样可能会降低系统的安全性。

另外记得安装网络配置相关的软件包,比如 networkmanager,以免重启后没有网。

推荐阅读一下常用设置,如果没有其他要配置的,就可以重启进新系统了。

安装后的配置

重启进入新系统后,因为还未安装图形界面,会进入 tty,因为之后要恢复家目录文件,所以这里暂时先不用普通用户登录,而是登录进 root 用户,开始着手恢复家目录文件,将之前用于备份家目录的移动硬盘重新挂载到 /mnt 目录,一样使用 rsync 恢复文件,只需将之前备份命令里两个路径互换位置即可:

1
rsync -avrh --progress /mnt/backup/ /home/

恢复过程同样需要较长时间,请耐心等待,恢复完成后退出 root 登录,使用普通用户登录。参照之前备份的软件包列表将所需的软件包装回来,再启用一些需要的服务,就可以正常使用了,就和重装前一样。

快照

btrfs 文件系统最吸引人的特性之一就是快照,通过快照可以方便地回滚系统,虽然我们也可以在命令行手动创建快照,但多少有些麻烦,为了更好地创建和管理快照,可以借助一些其他工具,我使用的是 LinuxMint 团队开发的 Timeshift,注意 Timeshift 只支持 Ubuntu 类型的子卷布局,这在之前的分区过程中已经搞定了。只需从 AUR 安装,之后打开按照向导一路设置就好了,记得要启用 cronie 服务,sudo systemctl enable cronie.service --now,以保证 Timeshift 能够定时创建快照。此外也可以安装 timeshift-autosnap,这个包添加了一个 pacman hook,可以在每次系统升级前自动创建快照。

接下来安装 grub-btrfs,这个软件可以在每次重新生成 grub 配置文件时添加快照的入口,可以在不恢复快照的情况下直接启动进入快照,方便故障排查。若是觉得每次创建快照后都要手动运行 grub-mkconfig 过于麻烦,这个包还提供了一个 systemd 服务 grub-btrfsd.service,需先安装 grub-btrfs 的可选依赖 inotify-tools,然后启用这个服务 sudo systemctl enable grub-btrfsd.service --now 就可以在每次创建快照后自动生成 grub 配置文件了,不过这个服务默认监视的快照路径在 /.snapshots,而 Timeshift 创建的快照是一个动态变化的路径,想要让它监视 Timeshift 的快照路径需要编辑 service 文件。一般情况下不推荐直接编辑位于 /usr/lib/systemd/system/ 下的 service 文件,因为软件包升级会将编辑后的文件覆盖掉,还好 systemd 提供了解决方案,运行 sudo systemctl edit --full grub-btrfsd ,这个命令会将 /usr/lib/systemd/system/grub-btrfsd.service 文件复制到 /etc/systemd/system/grub-btrfsd.service,再用系统默认的文件编辑器打开,这样编辑后的文件就不会被覆盖掉了,找到下面这一行:

1
ExecStart=/usr/bin/grub-btrfsd --syslog /.snapshots

修改为:

1
ExecStart=/usr/bin/grub-btrfsd --syslog --timeshift-auto

这样 grub-btrfs 就会监视 Timeshift 创建的快照了。

Timeshift 创建的快照默认是可读写的,但若用其他的快照管理程序,创建的快照可能是只读的,这种情况下,直接启动进入快照可能会发生错误,这种情况 grub-btrfs 也提供了解决方案,grub-btrfs 提供了一个 grub-btrfs-overlayfs 钩子,编辑 /etc/mkinitcpio.conf,找到 HOOKS 一行,在括号最后添加 grub-btrfs-overlayfs,比如这样:

1
HOOKS=(base udev autodetect modconf block filesystems keyboard fsck grub-btrfs-overlayfs)

然后重新生成 initramfs,sudo mkinitcpio -P。在这之后创建的只读快照,将会以 overlayfs 的形式启动进入,所有的改动将会存储在内存里,重启后都会消失,逻辑和大多数系统的 live-cd 安装镜像差不多。

休眠到硬盘

休眠到硬盘(又称 S4 睡眠),是将当前系统的状态存入硬盘的交换空间,然后完全断开电源,相比于常规的挂起到内存(又称 S3 睡眠),休眠时几乎不消耗电量,但是恢复时速度要更慢。

因为在之前的系统安装过程中我已经配置好了一个单独的足够大的 swap 分区,为了休眠到硬盘,需要告诉系统如何休眠到 swap 分区,首先配置 initramfs,编辑 /etc/mkinitcpio.conf,找到 HOOKS 一行,在括号中加入 resume,并且保证 resume 一定要在 udev 之后,比如这样:

1
HOOKS=(base udev autodetect modconf keyboard keymap consolefont block filesystems resume fsck grub-btrfs-overlayfs)

之后重新生成 initramfs,sudo mkinitcpio -P

再然后需要添加一个内核参数 resume ,指定 swap 分区的设备,参数值支持所有块设备持久化命名方式 ,如分区设备号,如 resume=/dev/sda2,或分区 UUID,如 resume=UUID=5514c3aa-63ee-49ec-920d-859b00c676fe,因为在多硬盘的机器上,硬盘的设备号可能会改变,所以还是更推荐使用分区 UUID,运行 sudo blkid 可以获取分区的 UUID:

1
2
3
4
$ sudo blkid
/dev/sda3: UUID="0929463f-13fe-457b-965a-8382b07a1d5c" UUID_SUB="175a979b-1fa8-437b-9715-acd48864494f" BLOCK_SIZE="4096" TYPE="btrfs" PARTLABEL="Linux filesystem" PARTUUID="0ca55fc8-f4c8-42d8-8b1c-620595fa134f"
/dev/sda2: UUID="5514c3aa-63ee-49ec-920d-859b00c676fe" TYPE="swap" PARTLABEL="Linux swap" PARTUUID="2e482d5e-2295-4b58-bdc2-6a1aab0e0af4"
/dev/sda1: UUID="4567-9EEB" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="EFI system partition" PARTUUID="24847dd6-c006-46a6-b91e-00466fb19ad4"

我的 swap 分区是 /dev/sda2,那么 UUID 就是 5514c3aa-63ee-49ec-920d-859b00c676fe。编辑 /etc/default/grub,找到 GRUB_CMDLINE_LINUX_DEFAULT 一行,将所需的内核参数填入引号中,如:

1
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet resume=UUID=5514c3aa-63ee-49ec-920d-859b00c676fe"

然后重新生成 grub 配置文件,sudo grub-mkconfig -o /boot/grub/grub.cfg

重启,运行 systemctl hibernate,系统就可以进入休眠状态了,按下电源键,就可以从休眠状态恢复。但这样有些麻烦,我们可以配置在短按电源键或笔记本合盖时进入休眠状态,编辑 /etc/systemd/logind.conf,我配置的是短按电源键进入休眠,加入或修改 HandlePowerKey=hibernate 一行,若想要配置合盖休眠,加入或修改 HandleLidSwitch=hibernate 一行,要记得删除行首的井号注释。重启后就可以通过短按电源键或合盖休眠了。

不过要注意休眠到硬盘的功能可能会在特定机型上出现问题,有时不同的内核版本也会影响休眠的正常工作,我前些天就遇到过问题,具体可以看我之前的文章。对于不同的机型,请自行测试是否有问题,对于出现的问题,建议阅读 Arch wiki 相关的页面,以及善用搜索引擎。

一些杂项配置

做完以上这些,系统差不多就可以正常使用了,但是你目前仍然无法享受到大多数发行版已经提前配置好的特性,因为这是 The Arch Way,什么东西都要自己配置,以下是我根据我个人的使用情况进行的可选的杂项配置,仅供参考。

机型问题修复

在一些锐龙处理器的机器上会出现 Linux 系统卡死的情况,只要系统负载稍微大一点,处理器核心温度一高就会卡死,搜索了一圈,我目前找到的最简单的解决方法是添加一个内核参数 idle=nomwait,编辑 /etc/default/grub,找到 GRUB_CMDLINE_LINUX_DEFAULT 一行,在引号中添加 idle=nomwait,比如这样:

1
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet resume=UUID=5514c3aa-63ee-49ec-920d-859b00c676fe idle=nomwait"

然后重新生成 grub 配置文件 sudo grub-mkconfig -o /boot/grub/grub.cfg,重启,再尝试运行一些负载较大的软件或游戏,会发现即使运行较长时间,系统也不会卡死了。不过代价是可能会导致系统在空载状态下功耗增加。

2023-05-13 更新

在最近一段时间的使用中,我又遇到了系统卡死的情况,但貌似和系统高负载没有关系,有时刚开机什么都没干就卡死了,使用主线内核卡死概率较高,切换回 lts 内核后,卡死的次数少了很多,但还是无法避免。最后我参照这篇文章中的内容禁用了锐龙处理器的 C6 状态,到现在为止用了好几天了没有再出现过卡死的问题,在这里记录一下:

首先安装 zenstates-git 包;

编辑 /etc/modules-load.d/modules.conf,是个空文件,添加内容 msr

添加一个服务文件 /etc/systemd/system/disable_c6.service

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=Ryzen Disable C6
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=basic.target

[Service]
Type=oneshot
ExecStart=/usr/bin/zenstates --c6-disable

[Install]
WantedBy=basic.target

最后启用服务:

1
2
sudo systemctl daemon-reload
systemctl enable disable_c6.service

BBR 算法

谷歌开发的BBR 拥塞控制算法,可以实现更高的带宽和更低的延迟,想要优化网速,可以尝试开启这个功能,首先加载内核模块 tcp_bbrsudo modprobe tcp_bbr,之后编辑 /etc/sysctl.d/30-bbr.conf

1
2
net.core.default_qdisc = cake
net.ipv4.tcp_congestion_control = bbr

之后重启,应该就能生效了。

ipv6 隐私扩展

使用 SLAAC 获取的 ipv6 地址,不同于 ipv4 时代使用 NAT 和 dhcp 获取到的内网地址,是全球唯一的公网地址,公网地址更容易被攻击,另外获取的 ipv6 地址是由运营商下发的地址前缀和根据本机网卡 MAC 地址计算出来的后缀组成的,攻击者很有可能根据 ipv6 后缀反推出网卡的 MAC 地址,增大了其危险性。为了解决这个问题,ipv6 提供了一个隐私扩展特性,允许在常规的 ipv6 地址之外额外生成一个临时地址,在连接网络时会优先使用临时地址,从而增加了安全性。要启用 ipv6 隐私扩展,需要编辑 /etc/sysctl.d/40-ipv6.conf

1
2
3
4
5
net.ipv6.conf.all.use_tempaddr = 2
net.ipv6.conf.default.use_tempaddr = 2
net.ipv6.conf.nic0.use_tempaddr = 2
...
net.ipv6.conf.nicN.use_tempaddr = 2

上面的 nic0nicN 要改成机器的网络接口名称,有几个就添加几个,不过若是配合 NetworkManager 使用,只添加前两行应该就够了。

之后重启,应该就能生效了。

加密 DNS

在浏览网页时,有时进入一个正常的网站,会莫名被跳转到钓鱼网站,这很有可能是系统 DNS 被污染了,因为常规的 DNS 协议使用的是 udp 明文传输,很容易被攻击者监听并篡改,而各大运营商默认分配的 DNS 是重点的污染对象,想要避免这个问题,就要使用加密的 DNS 协议。

systemd 自带的 systemd-resolved 其实已经支持了加密 DNS 协议,但是目前只支持 DNS-over-TLS,安全性相对较差一些,为了使用其他的加密 DNS 程序,需要禁用这个服务 sudo systemctl disable systemd-resolved.service --now。我选择的软件是 dnscrypt-proxy,支持一些最新的加密 DNS 特性,比如使用 HTTP3 的 DNS-over-HTTPS 协议,具体配置方法在这里,不再赘述。想要使用其他软件,可以看这里

加密 DNS 配置完成后,会与远程的加密 DNS 服务器连接,转发 DNS 请求到本地的 53 端口,但系统默认使用上级路由器 dhcp 分配的 DNS 服务器。想要修改系统默认使用的 DNS 服务器,最直接的方法是编辑 /etc/resolv.conf,在最顶部添加一行 nameserver 127.0.0.1,这样就能默认使用本地 DNS 服务器了,但问题是很多网络管理程序,包括 NetworkManager 都会修改这个文件,所以在重启后 /etc/resolv.conf 很有可能会变回默认。所以使用 NetworkManager 时,更有效的方法是编辑 NetworkManager 的配置文件,编辑 /etc/NetworkManager/conf.d/dns-servers.conf

1
2
[global-dns-domain-*]
servers=127.0.0.1

之后重启服务 sudo systemctl restart NetworkManager.service,这样无论连接什么网络,系统都会默认使用本地的 DNS 服务器了。

另外 Chromium 和 Firefox 浏览器都已经支持了加密 DNS,所以也可以在浏览器对应的配置项开启加密 DNS,这样加密 DNS 将只对浏览器生效。

随机 MAC 地址

NetworkManager 还有一个特性就是随机 MAC 地址,开启之后可以增加安全性,NetworkManager 默认开启了在 wifi 扫描时随机 MAC 地址,想要配置随机 MAC 地址,可以编辑 /etc/NetworkManager/conf.d/rand_mac.conf

1
2
3
4
5
6
[device-mac-randomization]
wifi.scan-rand-mac-address=yes

[connection-mac-randomization]
ethernet.cloned-mac-address=stable
wifi.cloned-mac-address=stable

wifi.scan-rand-mac-address 决定在 wifi 扫描时是否开启随机 MAC 地址,若需要固定的 MAC 地址,可以设为 no。ethernet.cloned-mac-addresswifi.cloned-mac-address 决定了连接有线网络和 wifi 网络时是否开启随机 MAC 地址,可用的值有:

  • 指定的 MAC 地址,连接时使用手动指定的 MAC 地址;
  • permanent,不改变 MAC 地址;
  • preserve,在网卡激活后不改变 MAC 地址;
  • random,在每次连接时都使用随机 MAC 地址;
  • stable,在初次连接一个网络时使用随机 MAC 地址,之后每次连接相同的网络都使用相同的 MAC 地址。

修改完后重启 NetworkManager 服务生效。

缓解关机卡 90 秒的问题

Linux 系统在关机时,偶尔会遇见卡住不动,要等大约 90 秒才可以关机的情况,这似乎是 systemd 的问题,systemd 以为有服务没有终止,但实际上没有,就只能等待直到强行停止,这个等待的时间默认就是 90 秒。

虽然不能完全解决这个问题,但至少可以修改它等待的时间,编辑 /etc/systemd/system.conf,添加或修改 DefaultTimeoutStopSec=90s 一行,记得删除行首井号注释,把时间改成一个较短的时间,比如 5 秒,这样等待的时间就会大大缩短了。

grub 美化

grub 是很多发行版使用的默认 bootloader,同时大部分 Linux 发行版都会默认对 grub 启动界面做一些美化,然而根据 The Arch Way,Arch Linux 默认同样不会对 grub 做多余的配置,默认就只是一个黑乎乎的菜单界面。

想要美化 grub 启动页面,最简单的方法是使用现成的 grub 主题,grub 软件包默认已经自带了一个主题,位于 /usr/share/grub/themes/starfield/,官方源中有 grub 主题 grub-theme-vimixbreeze-grub,AUR 中也有很多 grub 主题,另外也可以在这里手动下载主题。

用包管理器安装的主题也好,手动下载的主题也好,主题文件夹里面都会有一个 theme.txt 文件,运行 pacman -Ql package 可以列出指定软件包安装的所有文件,找到想要使用的主题对应的 theme.txt 文件,以 grub 自带的 starfield 主题为例,路径在 /usr/share/grub/themes/starfield/theme.txt,编辑 /etc/default/grub,找到 GRUB_THEME 一行,删除行首的井号注释,并将引号内的内容改成对应的 theme.txt 路径,比如:

1
GRUB_THEME="/usr/share/grub/themes/starfield/theme.txt"

之后重新生成 grub 配置文件,sudo grub-mkconfig -o /boot/grub/grub.cfg,这样下次开机时就可以看到美化后的 grub 菜单了。

pacman 配置

Arch linux 的包管理器 pacman 也有一些有用的配置项默认没有开启,编辑 /etc/pacman.conf,首先启用 32 位软件源 multilib,以便安装一些 32 位软件,比如 steam,取消注释以下两行:

1
2
[multilib]
Include = /etc/pacman.d/mirrorlist

之后在 [options] 下找到并取消注释:Color,启用彩色高亮;VerbosePkgLists,在安装或升级软件时显示详细变化;ParallelDownloads = 5,启用并行下载,提高下载速度。另外添加一行 IloveCandy,这是 pacman 的一个有趣的小彩蛋,可以让进度条变成吃豆人的样子。

添加第三方软件源

ArchlinuxCN

这是 ArchlinuxCN 社区维护的软件仓库,包含了很多中文用户常用软件包。以北外镜像站为例,在 /etc/pacman.conf 末尾添加如下两行:

1
2
[archlinuxcn]
Server = https://mirrors.bfsu.edu.cn/archlinuxcn/$arch

之后运行 sudo pacman -Sy archlinuxcn-keyring 以刷新密钥,另外可选的也可以安装 archlinuxcn-mirrorlist 包,会安装一个 /etc/pacman.d/archlinuxcn-mirrorlist 镜像列表,编辑这个文件,将最快的镜像源(一般可选北外、清华、华科的镜像等)移动到最顶部并删除注释,再次编辑 /etc/pacman.conf,将软件源修改为:

1
2
[archlinuxcn]
Include = /etc/pacman.d/archlinuxcn-mirrorlist

Chaotic-AUR

Chaotic-AUR 包含了很多构建好的 AUR 软件包,若想在安装 AUR 软件包时节省一些时间,可以添加这个软件源:

1
2
3
sudo pacman-key --recv-key FBA220DFC880C036 --keyserver keyserver.ubuntu.com
sudo pacman-key --lsign-key FBA220DFC880C036
sudo pacman -U 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-keyring.pkg.tar.zst' 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-mirrorlist.pkg.tar.zst'

/etc/pacman.conf 末尾添加如下两行:

1
2
[chaotic-aur]
Include = /etc/pacman.d/chaotic-mirrorlist

之后编辑 /etc/pacman.d/chaotic-mirrorlist 镜像列表,Chaotic-AUR 之前有一个托管在阿里云的国内镜像,相对速度快一些,但前段时间不知为何这个镜像没有了,目前国内最近的镜像是在韩国和印度,可以将这两个镜像放在最开头,虽然也不太快,但至少能用。

ALHP

ALHP 软件源将 Arch Linux 官方源中的软件包进行了重新编译,使用了 x86-64-v2x86-64-v3 优化,可以提升一部分性能。

添加这个软件源之前,需要先确认当前机器是否支持 x86-64-v2x86-64-v3,运行 /lib/ld-linux-x86-64.so.2 --help,若输出中有:

1
2
3
4
Subdirectories of glibc-hwcaps directories, in priority order:
x86-64-v4
x86-64-v3 (supported, searched)
x86-64-v2 (supported, searched)

说明机器支持 x86-64-v2x86-64-v3

之后从 AUR 安装 alhp-keyringalhp-mirrorlist,之后编辑 /etc/pacman.d/alhp-mirrorlist 镜像列表,alhp 在国内有上海科技大学镜像站一个镜像源,这个镜像源速度不太稳定,不过也比其他国外镜像快许多,推荐将这个镜像源放在首位。之后编辑 /etc/pacman.conf,添加:

1
2
3
4
5
6
7
8
[core-x86-64-v3]
Include = /etc/pacman.d/alhp-mirrorlist

[extra-x86-64-v3]
Include = /etc/pacman.d/alhp-mirrorlist

[community-x86-64-v3]
Include = /etc/pacman.d/alhp-mirrorlist

若系统只支持 x86-64-v2,需要将 x86-64-v3 改成 x86-64-v2,另外一定要添加在官方的 [core][extra][community] 之前,保证软件包优先于官方包安装。

之后运行 sudo pacman -Suy,这会安装很多软件包,需要较长时间,完成后重启。添加了这个软件源后,跑了下分没有明显变化,但是在游戏中帧率好像高了些,还稳定了些,有点玄学,提升聊胜于无吧。

若遇到了问题,想要禁用这个软件源,只需删除 /etc/pacman.conf 中对应的内容,卸载 alhp-keyringalhp-mirrorlist,之后运行 sudo pacman -Suuy,就可以将所有软件包恢复到官方了。

时间同步

systemd 自带了一个 systemd-timesyncd 服务,提供了简单的时间同步服务,若是没有特别需求,这个服务已经够用了。不过这个服务默认使用的是 Arch Linux 自己的 NTP 服务器,在国内访问较慢,有时会导致时间同步失败,为了更快地同步时间,可以选用其他的 NTP 服务器,我选用了中国 NTP 快速授时服务和中国计量科学研究院 NIM 授时服务的 NTP 服务器,编辑 /etc/systemd/timesyncd.conf,添加或编辑如下一行:

1
NTP=cn.ntp.org.cn ntp1.nim.ac.cn

然后重启 systemd-timesyncd.service,之后运行 timedatectl timesync-status 便可查看时间同步状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ timedatectl timesync-status
Server: 2001:da8:9000::130 (cn.ntp.org.cn)
Poll interval: 34min 8s (min: 32s; max 34min 8s)
Leap: normal
Version: 4
Stratum: 1
Reference: PTP
Precision: 1us (-26)
Root distance: 45us (max: 5s)
Offset: -2.957ms
Delay: 31.415ms
Jitter: 4.354ms
Packet count: 18
Frequency: -4.740ppm

可以看到这里 offset 只有不到 3 毫秒,还是很精准的。

笔记本续航优化

Arch Linux 在笔记本平台相比于 Windows 和其他功能齐全的 Linux 发行版一个比较大的劣势就是续航较差,因为其默认并没有为笔记本续航做优化。

而 Linux 平台笔记本续航优化的软件,最为人熟知且被最多人推荐的是 TLP,并且已经被很多发行版预装,这个软件支持很多设备的省电模式优化,如 CPU、无线网络、蓝牙、硬盘等等,配置好了的话可以大大延长笔记本的续航时间。但是这个软件在我的笔记本上运行似乎有些问题,在断开电源后一段时间后外接键盘会不能用,这大概是 USB 自动休眠的问题,但就算我在配置文件中禁用了 USB 自动休眠,问题也没解决。并且 TLP 默认对省电模式的性能限制有点狠,CPU 无法睿频,导致在电池模式下干什么事情都挺卡的。因为我的使用情况大部分时间笔记本都连着电源,所以续航不太敏感,所以我就一直没有装 TLP。

就在最近我发现了另外一个程序,叫 auto-cpufreq,顾名思义,这个程序负责自动调节 CPU 频率,连接电源时使用性能模式,断开电源后使用省电模式,并且不限制睿频,对于省电的效果可能没有 TLP 那么好,但因为它只负责调节 CPU,不会出现 TLP 上面好多设备不能用的玄学问题,并且这些设备的功耗也不是占大头。安装的话只需从 AUR 安装,无需进行过多设置,直接启用相关服务即可,sudo systemctl enable auto-cpufreq.service --now

五步工作法:

  1. 质疑每项要求。提出任何一项要求时,都应该附上提出这一要求的人。永远不要接受一项来自某个部门的要求,比如来自“法务部门”或者“安全部门”的要求。你必须知道提出这项要求的人的名字。接下来你应该质疑它,不管这个人有多聪明。聪明人提出的要求才是最危险的,因为人们不太可能质疑他们。这件事要一直做下去,即便这项要求来自马斯克本人。质疑后,大家就要改进要求,让它变得不那么愚蠢。
  2. 删除要求当中所有你能删除的部分和流程,虽然你可能还得把它们加回来。事实上,你如果最后加回来的部分还不到删除部分的10%,那就说明你删减得还不够。
  3. 简化和优化。这应该放在第2步之后,因为人们常犯的错误就是简化和优化一个原本不应该存在的部分或者流程。
  4. 加快周转时间。每个流程都可以加快,但只有遵循了前三个步骤之后才能这么做。在特斯拉工厂,我错误地把很多精力花在加快生产流程上,后来我才意识到有些流程原本就应该被拿掉。
  5. 自动化。在内华达工厂和弗里蒙特工厂犯下的一个大错就是我一开始试图将每个步骤进行自动化改造。我们本应该先质疑所有要求,删除不必要的部分和流程,把问题筛出来、处理掉,然后再推进自动化。

这套工作法有时还衍生出一些推论,包括:

  • 所有技术经理都必须有实战经验,比如说软件团队的管理人员必须至少花20%的时间进行编程,太阳能屋顶业务的经理必须花时间在屋顶上亲自做安装工作。否则光说不练,他们就像是不会骑马的骑兵队队长、不会舞刀弄枪的将军。
  • “你好,我好,大家好”是很危险的,人们会因此不再质疑同事的工作成果。人们天然有一种倾向是不想把要好的同事踢下船,而这种危险倾向一定要避免。
  • 犯错没关系,但错了还不肯低头就不行。
  • 永远不要要求你的团队做你自己都不愿意做的事。
  • 每当有问题需要解决时,不要只与你直接管理的相关负责人聊。深入调研就要跨层级沟通,去跟你属下的属下直接交流吧。
  • 招聘要招态度端正的人。技能是可以教的,但要扭转一个人的工作态度可就太费劲了,得给他“换个脑子”。
  • 疯狂的紧迫感是我们公司运作的法则。
  • 唯一要遵守的规则就是物理学定律能推导出来的规则,其他一切都只是建议。

如何高效率学习

学习方法

费曼学习法

费曼学习法的本质就是在于使用输出倒逼输入,通过讲自己以为明白了的东西以教别人的方式输出来达到验证自己,实际上是一个通过输出来发现缺陷和问题的过程,同时要求在教别人的时候用最通俗易懂的方式,这个要求本质上是要求把知识解构和重构的过程,也就是变成自己的东西,这个过程实际上就是利用了第一性原理,就是讲知识蒸馏,只剩下最根本的逻辑和公理,之后运用这套最基本的原理类的东西重构成一个新的案例。

感觉费曼学习法这一套流程中蕴含了其他几种学习原理,首先教会别人其实本质上就是知行合一的一种形式,教这个动作就是行,在教别人的时候遇到讲不通的地方,其实这个原理就是在行中发现问题,也只有行才能真正发现好问题,通过行发现的问题再回过头去学去搞明白,如此循环就是知行合一的体现。同时为什么选择教这个动作作为行而不是其他呢,这其实蕴含了其他原理在里面,就是第一性原理,其实也就是解构和重构的过程,因为教的对象是一个从来都没有接触过这方面的人,所以只能讲述最基本的原理,从而就可去掉一些附着的东西而直击本质,也就是第一性原理,而第一性原理也就是要抓住主要矛盾主要原理,去除掉不影响本质的东西,也就是解构,也叫解耦合,解构完成之后通过通俗易懂的表达教给别人,事先重构,也就是说,教这个动作能够让人在不经意间就完成解构和重构的过程。

知—> 行—> 第一性原理—> 发现问题—> 知

第一性原理

本质是解构,换一种表达就是人们常说的透过现象看本质,将无关紧要的附着物抛开,只关注最本质最重要的部分,这个原理可以指导“行”。从最基本的原理或者逻辑出发,理解并改进。

知行合一

知者行之始,行者知之成。知和行本来就是同一个事物。仅仅学习而不去实践,便不是学习。

凡明不得、行不去,须反在自心上体当,即可通。

学会提出问题

相比较回答问题,更重要的是提出问题,提出高质量的问题,如何提出高质量的问题,这就取决于对问题本质的认识

模仿人物

马斯克

拥有清晰的目标、专注、第一性原理、三人行必有我师焉、跨学科学习、大量阅读

费曼

兴趣、费曼学习法

蔡志忠

终身阅读、主题性阅读,先设定一个主题,然后去阅读

看书应该像构筑房子般

山姆 奥特曼

  1. 跨领域学习

    不要局限于自己的领域学习。 从不相关的领域中获得灵感,并将其应用于自己的领域。 最具创新的解决方案常常是不同学科的交叉融合。

  2. 建立学习仪式

    每天花时间专注于学习。建立一个有规律的习惯,可以是:

    • 每天早上阅读一个小时

    • 上班途中收听播客

    • 晚上上在线课程

    深度工作需要持之以恒。

  3. 发挥科技的作用

    我们生活在一个信息超载的时代。利用人工智能工具整合信息。 跟随新的学习科技发展。 如果不利用科技,你将被抛在后面。

  4. 建立强大的个人网络

    人际关系是学习的乘数效应。建立一个强大的合作伙伴网络。

  5. 寻找可以指导和挑战你的导师。反过来,慷慨地帮助他人

    一个强大的网络可以使你接触新的观点和学习机会。

  6. 培养专注力

    25岁以上的成年人的神经系统储存新信息的空间较小。 强迫你的大脑接受新的模式:

    • 不要多任务

    • 集中精力工作

    • 远离电视和手机等干扰

  7. 充满好奇心

    追求那些你深深着迷的话题,而不仅仅是流行的话题。 任何领域中最成功的人都是最好奇的人。 读书是为了满足你的求知欲望,而不是为了炫耀或完成的缘故。

  8. 应用你所学的知识

    知识如果不应用只会导致停滞不前。学到新知识后,要问问自己:

    • 我如何应用这个概念?

    • 我可以用这个做什么项目?

    • 我如何教别人这个?

    应用是巩固理解的关键

  9. 接受重复

    在注意力不集中的时代,重复对于保持新知识至关重要。 建立系统,反复接触知识,直到它深入你的记忆。 即使是天才也会反复学习同样的材料。

  10. 教给他人

    巩固你的理解最好的方法之一是将概念教给他人。当你可以解释一个想法时,这是真正的掌握。 通过:

    • 写作

    • 指导

    • 公开演讲

    传授知识对学生和教师都有益处。

  11. 学习销售

    Altman称销售是“最重要的技能”。学会说服和沟通是至关重要的。 掌握传达自己想法的艺术。学会激励和激发他人。 销售对于创业者、员工和学者都是必不可少的。

  12. 敢于显得愚蠢

    对于很多人来说,害怕显得愚蠢是他们学习的绊脚石。 拥抱初学者的心态。提出天真的问题。承认自己不懂的事情。 为了学习的好处,放下自己的自尊是微不足道的代价。

  13. 热爱过程

    学习不仅仅是达到目的,而是目的本身。 热爱探索和成长的过程。培养对知识的真正热情。 学习的乐趣才是最终的回报。

如何高效率做一件事情

看清本质

学会提出问题

看清本质是提出好问题的前提

问题导向

带着问题在资料中找答案

迭代思想

做任何一件事情,最好的办法就是先有个初始解,然后进行迭代。

  1. 不管多烂,先搞出来个初始解
  2. 找个可以提升的方向
  3. 结合自身能力,设置步长
  4. 不断重复2-3步,不断进行迭代

如何做笔记

三个原则可以帮助你有效地记笔记

  1. 笔记必须符合你的思维方式

    做笔记要按照自己的思考方式,不能原封不动地按照老师(或者书本)的讲解方式。这样不仅你写起来更轻松,而且将来回顾笔记的时候,你也更容易理解自己当时的想法。

  2. 笔记必须代表你的知识

    笔记不要仅仅复制/粘贴他人的话语,而要用自己的语言表达。你不妨标记清楚,哪些地方是已经理解的,哪些地方还没有理解或者有疑问。

  3. 笔记必须可以轻松检索

    为了最大限度利用自己的笔记(其实也是节约自己的时间),它必须可以方便地检索。你要为每个部分写一个标题,并且定期整理出一份目录。

笛卡尔的思考秘籍:

第一、从清楚明白、无需怀疑的公理开始;

第二、复杂事情切分成部分,切分到可以处理为止;

第三、按顺序思考、从最简单的着手;

第四、考虑问题要全面、列举完全。