<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Guangjing Wang</title>
    <description>Guangjing Wang is an Assistant Professor at USF researching agentic AI, secure and trustworthy AI, mobile sensing, and data management.</description>
    <link>https://guangjing.wang/</link>
    <atom:link href="https://guangjing.wang/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Fri, 23 Oct 2026 20:39:12 +0000</pubDate>
    <lastBuildDate>Fri, 23 Oct 2026 20:39:12 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Conference Notes</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#acm-sensys2022&quot; id=&quot;markdown-toc-acm-sensys2022&quot;&gt;&lt;strong&gt;ACM SenSys’2022&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#acm-ccs2022&quot; id=&quot;markdown-toc-acm-ccs2022&quot;&gt;&lt;strong&gt;ACM CCS’2022&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I find it engaging to document the topics covered in conference sessions as it provides us with a fundamental understanding of the prevailing trends in research areas.&lt;/p&gt;

&lt;h3 id=&quot;acm-sensys2022&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://sensys.acm.org/2022/&quot;&gt;ACM SenSys’2022&lt;/a&gt;&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;RF Sensing&lt;/li&gt;
  &lt;li&gt;New Applications&lt;/li&gt;
  &lt;li&gt;Low-power Systems&lt;/li&gt;
  &lt;li&gt;Lighting and Acoustic Sensing&lt;/li&gt;
  &lt;li&gt;Machine Learning for Mobile Systems&lt;/li&gt;
  &lt;li&gt;System for Voice, Speech and Video Processing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;acm-ccs2022&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://www.sigsac.org/ccs/CCS2022/&quot;&gt;ACM CCS’2022&lt;/a&gt;&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Applied Crypto
    &lt;ul&gt;
      &lt;li&gt;Digital Signatures&lt;/li&gt;
      &lt;li&gt;Digital Currencies and Blockchains&lt;/li&gt;
      &lt;li&gt;Zero-Knowledge&lt;/li&gt;
      &lt;li&gt;Cryptographic Protocols&lt;/li&gt;
      &lt;li&gt;Advanced Public-Key Encryption Schemes&lt;/li&gt;
      &lt;li&gt;Key Exchange&lt;/li&gt;
      &lt;li&gt;Security Multiparty Computation&lt;/li&gt;
      &lt;li&gt;Private-Set Intersection&lt;/li&gt;
      &lt;li&gt;Symmetric-Key Encryption and Attacks&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Software Security
    &lt;ul&gt;
      &lt;li&gt;Fuzzing&lt;/li&gt;
      &lt;li&gt;Analysis&lt;/li&gt;
      &lt;li&gt;Information Leakage and Access Control&lt;/li&gt;
      &lt;li&gt;Hardware-Assisted Defense&lt;/li&gt;
      &lt;li&gt;Vulnerability Detection&lt;/li&gt;
      &lt;li&gt;Defenses and Virtualization-based Security&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Web Security
    &lt;ul&gt;
      &lt;li&gt;Client Side Security&lt;/li&gt;
      &lt;li&gt;Server Side Security&lt;/li&gt;
      &lt;li&gt;Users Under Attack&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Network Security
    &lt;ul&gt;
      &lt;li&gt;Internet Security&lt;/li&gt;
      &lt;li&gt;Cloud and IoT Security&lt;/li&gt;
      &lt;li&gt;Network Vulnerabilities&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Cyber-Physical System
    &lt;ul&gt;
      &lt;li&gt;CPS and IoT Security&lt;/li&gt;
      &lt;li&gt;General Attacks and Defense&lt;/li&gt;
      &lt;li&gt;Side Channel Attacks
        &lt;ul&gt;
          &lt;li&gt;Hardware and Microarchitecture&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Machine Learning
    &lt;ul&gt;
      &lt;li&gt;Poisoning and Backdooring ML&lt;/li&gt;
      &lt;li&gt;Inference Attacks to ML&lt;/li&gt;
      &lt;li&gt;ML for Network Security&lt;/li&gt;
      &lt;li&gt;Federated Learning Security&lt;/li&gt;
      &lt;li&gt;General Attacks to ML&lt;/li&gt;
      &lt;li&gt;Adversarial Examples in ML&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Privacy and Anonymity
    &lt;ul&gt;
      &lt;li&gt;Secure Query Answering&lt;/li&gt;
      &lt;li&gt;Ads and Location Privacy&lt;/li&gt;
      &lt;li&gt;Online, Mobile, Multimedia Privacy&lt;/li&gt;
      &lt;li&gt;Privacy Attacks in ML&lt;/li&gt;
      &lt;li&gt;Privacy Preserving Machine Learning&lt;/li&gt;
      &lt;li&gt;Federated Analytics and Learning&lt;/li&gt;
      &lt;li&gt;Differential Privacy&lt;/li&gt;
      &lt;li&gt;Privacy in Graphs&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Usability and Measurement
    &lt;ul&gt;
      &lt;li&gt;Finding Violations&lt;/li&gt;
      &lt;li&gt;Attacks&lt;/li&gt;
      &lt;li&gt;Security and Privacy Practices&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Blockchain and Distributed System&lt;/li&gt;
  &lt;li&gt;Hardware Security&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 31 Oct 2022 00:00:00 +0000</pubDate>
        <link>https://guangjing.wang/2022/10/31/conference-notes/</link>
        <guid isPermaLink="true">https://guangjing.wang/2022/10/31/conference-notes/</guid>
        
        <category>Conference</category>
        
        
        <category>Research</category>
        
      </item>
    
      <item>
        <title>Writing Notes</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#word&quot; id=&quot;markdown-toc-word&quot;&gt;&lt;strong&gt;Word&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#sentence&quot; id=&quot;markdown-toc-sentence&quot;&gt;&lt;strong&gt;Sentence&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#paragraph&quot; id=&quot;markdown-toc-paragraph&quot;&gt;&lt;strong&gt;Paragraph&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#email&quot; id=&quot;markdown-toc-email&quot;&gt;&lt;strong&gt;Email&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal of good writing is straightforward: to make your reader’s job as easy as possible. The trick is not to copy someone else’s voice, but rather to study what works and what does not in your own writing and that of others to formulate your own guide to effective communication.&lt;/p&gt;

&lt;p&gt;In &lt;a href=&quot;https://onlinelibrary.wiley.com/doi/full/10.1002/pro.514&quot;&gt;the art of writing science article&lt;/a&gt;, the author discusses some of the rules he has picked up for tackling each of these elements.&lt;/p&gt;

&lt;h3 id=&quot;word&quot;&gt;&lt;strong&gt;Word&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Jargon is one of the greatest enemies of clear scientific writing.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Do not invent new words or phrases if there is already a commonly used word or phrase that accurately fits the bill.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;If at all possible, avoid using abbreviations.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Word choice also impacts the precision of your writing. For example, “these data show” is less precise than “these data indicate” or “these data demonstrate”; although “show” can denote both “indicate” or “demonstrate,” the two words are not interchangeable as the former is synonymous with “suggest” and the latter with “prove”. Using the word “show” thus forces your readers to pause, break their stream of consciousness, and waste effort deciding what you meant.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;sentence&quot;&gt;&lt;strong&gt;Sentence&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Passive language, although extremely common in scientific writing, is a bore that your readers’ eyes will tend to glide over without taking in.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Be aware of long sentences. While it is good to vary your sentence length across a paragraph, longer sentences are generally harder to parse than their shorter brethren.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;paragraph&quot;&gt;&lt;strong&gt;Paragraph&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The first sentence of each paragraph should tell the reader what you expect them to get out of the paragraph that follows, which makes their job of following it far easier.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The first sentence of a paragraph generally should not refer to an idea in the paragraph above without, at the least, restating that idea. For this reason, I avoid starting paragraphs with phrases such as “However”, or “In contrast”.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A paragraph should discuss only a single idea and thus should have a single, unifying theme running throughout it.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Flow is an equally critical element of a good paragraph structure: every sentence in a paragraph should arise logically from the sentence before it, and transition logically into the sentence that follows.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A scientific paper is composed of specific elements: a title, an abstract, an introduction, methods, results, figures and captions, and, often, a stand‐alone discussion section.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Figure caption should be clear. I believe that the reader should be able to ascertain the entire story just by reading the figure captions. The first sentence of the figure caption should be, in effect, a title for the figure that clearly and concisely tells your readers what you expect them to learn from the figure.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;email&quot;&gt;&lt;strong&gt;Email&lt;/strong&gt;&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Thank you for the patience and valuable instructions!
With the continuation with previous mail, In the past two weeks, I have gone though multiple data sources including Factiva, Bloomberg, Reuters, analyst reports, industry reports and local news outlets looking for important updates on this topic.
There are multiple interesting aspects that I looked into…
Please find the updated attached excel sheet which contains all the information collected as instructed in your request. Also, In the spreadsheet attached, I have included the keywords and link for each news source, highlighted the cells for the newly added records for the period between 24 Dec- 31 Jan 2022.
Please do let me know your valuable advise on the shared excel sheet. Please don’t hesitate to contact me if you have any questions.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Mon, 26 Sep 2022 00:00:00 +0000</pubDate>
        <link>https://guangjing.wang/2022/09/26/writing-notes/</link>
        <guid isPermaLink="true">https://guangjing.wang/2022/09/26/writing-notes/</guid>
        
        <category>Paper</category>
        
        
        <category>Research</category>
        
      </item>
    
      <item>
        <title>Server Setup (3)</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#network&quot; id=&quot;markdown-toc-network&quot;&gt;&lt;strong&gt;Network&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#login&quot; id=&quot;markdown-toc-login&quot;&gt;&lt;strong&gt;Login&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#softwares&quot; id=&quot;markdown-toc-softwares&quot;&gt;&lt;strong&gt;Softwares&lt;/strong&gt;&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#anaconda&quot; id=&quot;markdown-toc-anaconda&quot;&gt;&lt;strong&gt;Anaconda&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#virtualenv&quot; id=&quot;markdown-toc-virtualenv&quot;&gt;&lt;strong&gt;Virtualenv&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#pytorch-and-tensorflow&quot; id=&quot;markdown-toc-pytorch-and-tensorflow&quot;&gt;&lt;strong&gt;Pytorch and Tensorflow&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#tmux-and-screen&quot; id=&quot;markdown-toc-tmux-and-screen&quot;&gt;&lt;strong&gt;Tmux and Screen&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#misc&quot; id=&quot;markdown-toc-misc&quot;&gt;&lt;strong&gt;MISC&lt;/strong&gt;&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#git&quot; id=&quot;markdown-toc-git&quot;&gt;&lt;strong&gt;Git&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#gpu-usage&quot; id=&quot;markdown-toc-gpu-usage&quot;&gt;&lt;strong&gt;GPU usage&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#file-transfer&quot; id=&quot;markdown-toc-file-transfer&quot;&gt;&lt;strong&gt;File Transfer&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#file-system&quot; id=&quot;markdown-toc-file-system&quot;&gt;&lt;strong&gt;File System&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#jupyterlab&quot; id=&quot;markdown-toc-jupyterlab&quot;&gt;&lt;strong&gt;JupyterLab&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#windows-related&quot; id=&quot;markdown-toc-windows-related&quot;&gt;&lt;strong&gt;Windows Related&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a quick guide for using Deep Learning Stack Server in OTML-SEIT labs. The basic configuration of the server is: TensorEX TS4-178672310 - 2x Gold 5218R, 16GBx16 DDR4, 2x 2TB NVMe SSD, 8x 8TB SATA HDD, 8x RTX A6000, Ubuntu 20.04 w/ EMLI Container Deep Learning Stack.&lt;/p&gt;

&lt;h3 id=&quot;network&quot;&gt;&lt;strong&gt;Network&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The server is maintained by DECS and OTML-SEIT labs in MSU, so make sure you can access the EGR network in MSU before logging into the server.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Activate your EGR Account before connecting to the server &lt;a href=&quot;https://www.egr.msu.edu/decs/myaccount/?page=activate&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;For Windows users, you can find Engineering VPN &lt;a href=&quot;https://www.egr.msu.edu/decs/how-to/new-engineering-vpn&quot;&gt;here&lt;/a&gt;. For more information about remote access and VPN setup, please visit &lt;a href=&quot;https://www.egr.msu.edu/decs/&quot;&gt;DECS&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;An alternative option is to use the jump server if you are outside of the MSU network:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ssh {netid}@scully.egr.ms.edu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;login&quot;&gt;&lt;strong&gt;Login&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Use ssh to log in as below: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ssh {netid}@otml-set.egr.ms.edu&lt;/code&gt;		&lt;em&gt;&lt;strong&gt;I miss U :)&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;/home/{netid}/&lt;/strong&gt;: Upon logging in you’ll have your usual EGR home directory at /home/{netid}, we do not recommend you do storage in the home folder. Instead, we have two other options.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;/localscratch/ and /localscratch2/&lt;/strong&gt;: Each is individual and non-redundant, but very durable; this way there is roughly 7TB worth of fast storage available for working from. Both of these are where other groups have their users make themselves a folder for their own access (named with their netid for ease of identification)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;/storage/&lt;/strong&gt;: It is slower than the NVMe, but has about 42 TB total usable; it is set up to allow the failure of 2 of the 8 drives without data loss. It is highly recommended that running your data from scratch, and then once results are done and ready to be archived/whatever, you can just copy/move them to /storage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;softwares&quot;&gt;&lt;strong&gt;Softwares&lt;/strong&gt;&lt;/h3&gt;

&lt;h4 id=&quot;anaconda&quot;&gt;&lt;strong&gt;Anaconda&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Do not install anaconda in your home folder since it will be large like 3.5G+. Instead, follow &lt;a href=&quot;https://docs.conda.io/projects/conda/en/latest/user-guide/install/linux.html&quot;&gt;conda install&lt;/a&gt; to install anaconda. Here is recommended:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/localscratch/{netid}/anaconda3

conda list
conda env list
conda create -n your_env_name python=X.X
conda install -n your_env_name [package]
conda remove -n python36 --all
conda activate your_env_name
source activate your_env_name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;virtualenv&quot;&gt;&lt;strong&gt;Virtualenv&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Virtualenv is a tool to create isolated Python environments. Follow &lt;a href=&quot;https://virtualenv.pypa.io/en/latest/installation.html&quot;&gt;virtualenv install&lt;/a&gt; to install virtualenv. In most cases, you will not need the sudo permission under virtualenv.&lt;/p&gt;

&lt;h4 id=&quot;pytorch-and-tensorflow&quot;&gt;&lt;strong&gt;Pytorch and Tensorflow&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Follow &lt;a href=&quot;https://pytorch.org/get-started/locally/&quot;&gt;pytorch install&lt;/a&gt; and &lt;a href=&quot;https://www.tensorflow.org/install&quot;&gt;tensorflow install&lt;/a&gt; here to install these two software.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The default GPU for OTML Lab (Prof. Liu)  is GPU ‘0’, ‘1’, ‘2’, ‘3’.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The default GPU for SEIT Lab (Prof. Yan)  is GPU ‘4’, ‘5’, ‘6’, ‘7’.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Be sure not to use multiple GPUs at the same time if one is enough!&lt;/strong&gt; If the other lab would like to use their default GPUs, you need to kill the jobs ASAP. Here are some ways to specify the number of GPUs you can use:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;export CUDA_VISIBLE_DEVICES=4 # Command example to use GPU &apos;4&apos;
python example.py
****************************************
CUDA_VISIBLE_DEVICES=4 python example.py
****************************************
os.environ[&quot;CUDA_VISIBLE_DEVICES&quot;] = &quot;4,5,6,7&quot; # Command example to use GPU &apos;4&apos;, must set before &apos;import torch&apos;
****************************************
config = tf.ConfigProto()
config.gpu_options.allow_growth = True # allocate gpu according to its need
config.gpu_options.per_process_gpu_memory_fraction = 0.4 # specifiy GPU memory fraction
****************************************
device = torch.device(&quot;cuda:0&quot; if torch.cuda.is_available() else &quot;cpu&quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;tmux-and-screen&quot;&gt;&lt;strong&gt;Tmux and Screen&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Tmux is a terminal multiplexer: it enables a number of terminals to be created, accessed, and controlled from a single screen. Tmux may be detached from a screen and continue running in the background, then later reattached. It is recommended to choose Tmux, and you can find a good guide to Tmux &lt;a href=&quot;https://www.hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/&quot;&gt;HERE&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here are some example usages:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tmux new -s &amp;lt;session-name&amp;gt;
tmux detach
tmux attach -t &amp;lt;session-name&amp;gt;
tmux kill-session -t &amp;lt;session-name&amp;gt;
tmux switch -t &amp;lt;session-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;An alternative choice is to use screen. You can start a screen session and then open any number of windows (virtual terminals) inside that session. Processes running in Screen will continue to run when their window is not visible even if you get disconnected. Here are some example usages:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt install screen
screen -S yourname # create a named session， 
screen -r yourname # reattach to your session
screen -d -r yourname # deattach and reattach to your session
screen -ls # list all sessions

Ctrl-A-Esc to see more content on the screen; Esc to exit the mode;
your_command|less to see more content;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;misc&quot;&gt;&lt;strong&gt;MISC&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Here are some other commands you may find helpful.&lt;/p&gt;

&lt;h4 id=&quot;git&quot;&gt;&lt;strong&gt;Git&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Here are some git commands in case you may use git on the server:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git status  # check git status
git add -A	# Add all new and changed files to the staging area
git commit -m &quot;[commit message]&quot; # Commit changes
git push -u origin [branch name] # Push changes to the remote repository (and remember the branch)
git diff file # Preview changes before merging
git checkout # Switch to a branch and discard the changes
git reset HEAD file # Discard changes in the staging area
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;gpu-usage&quot;&gt;&lt;strong&gt;GPU usage&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Use the below command for a breakdown of the GPU usage:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nvidia-smi
watch -n 1 nvidia-smi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;file-transfer&quot;&gt;&lt;strong&gt;File Transfer&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Here are some recommendations for transferring files:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;scp, rz/sz, FileZilla
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;file-system&quot;&gt;&lt;strong&gt;File System&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Ubuntu mount HPCC &lt;a href=&quot;https://tecadmin.net/install-sshfs-on-linux-and-mount-remote-filesystem/&quot;&gt;Reference&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sshfs user-name@hpcc.ms.edu:/mnt/home/user-name/ ./hpcc
sshfs user-name@otml-set.egr.ms.edu:/localscratch/user-name/ ./otml-set
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One thing that causes my disk being full is that the ~/.local/share/Trash becomes more than 300 GB.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;du: disk usage, &apos;-s&apos; means summary, &apos;-h&apos; means human readable
    du -sh /home/name/* | sort -hr
    du -h --max-depth=1 /home/name/
df: disk free, &apos;-h&apos; means human readable
    df -h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;jupyterlab&quot;&gt;&lt;strong&gt;JupyterLab&lt;/strong&gt;&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;Install Jupyterlab on the server. You may use conda to install.&lt;/li&gt;
  &lt;li&gt;Start Jupyterlab with no browser. You may need to activate the environment such as “conda activate dgl”.
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jupyter lab --no-browser --ip &quot;*&quot; --notebook-dir /localscratch/user-name/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Create a Screen: screen -S jupyter&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;You need to ssh in local terminal: ssh -L 8888:127.0.0.1:8888 user-name@otml-set.egr.ms.edu&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;I miss U :)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;windows-related&quot;&gt;&lt;strong&gt;Windows Related&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Recycle bin gets problem: dropped file are deleted permanately.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Solution: rd /s /q C:\$Recycle.bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Fri, 15 Oct 2021 00:00:00 +0000</pubDate>
        <link>https://guangjing.wang/2021/10/15/server-setup-three/</link>
        <guid isPermaLink="true">https://guangjing.wang/2021/10/15/server-setup-three/</guid>
        
        <category>Server</category>
        
        
        <category>System</category>
        
      </item>
    
      <item>
        <title>Server Setup (2)</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#installation&quot; id=&quot;markdown-toc-installation&quot;&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#usage&quot; id=&quot;markdown-toc-usage&quot;&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker serves as an open platform, enabling developers and system administrators to construct, transport, and execute distributed applications, whether they are on laptops, virtual machines in data centers, or in the cloud.&lt;/p&gt;

&lt;h3 id=&quot;installation&quot;&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Using Docker, developers package their applications and dependencies into a lightweight, portable container, and then publish it to any popular Linux machine, which can be virtualized and has extremely low container performance overhead. Docker images include Running environment and configuration, so Docker can simplify the deployment of multiple application instances. For example, web applications, background applications, database applications, big data applications such as Hadoop clusters, message queues, etc. can be packaged into a mirror for deployment.&lt;/p&gt;

&lt;p&gt;Install Docker on Centos: &lt;a href=&quot;http://www.runoob.com/docker/centos-docker-install.html&quot;&gt;Centos&lt;/a&gt;
Install Docker on Ubuntu: &lt;a href=&quot;http://www.runoob.com/docker/ubuntu-docker-install.html&quot;&gt;Ubuntu&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;uname -r // check kernel version
wget -qO- https://get.docker.com/ | sh　// download installation package
sudo usermod -aG docker runoob 　// commands prompted to enter after installation is complete
sudo service docker start　//start docker service, or using sudo systemctl start docker
docker ps -a　// query container
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;usage&quot;&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;“docker run” is only used when running for the first time. Put the image in the container. To start the container again in the future, you only need to use docker start (start the existing image, but you cannot specify the instructions to run when the container starts). , docker run is equivalent to performing two steps, placing the image in the container (docker create), and then starting the container to turn it into a runtime container (docker start).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;When using docker run to create a container, the standard operations Docker runs in the background include:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Check whether the specified image exists locally. If not, download it from the public warehouse.&lt;/li&gt;
      &lt;li&gt;Use the image to create and start a container.&lt;/li&gt;
      &lt;li&gt;Allocate a file system and mount a read-write layer outside the read-only image layer.&lt;/li&gt;
      &lt;li&gt;Bridge a virtual interface from the bridge interface configured on the host host to the container.&lt;/li&gt;
      &lt;li&gt;Configure an IP address from the address pool to the container.&lt;/li&gt;
      &lt;li&gt;Execute user-specified applications.&lt;/li&gt;
      &lt;li&gt;The container is terminated after execution is completed.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;You need to ensure that the container is stopped before deleting it. Use the stop command. Please note that the commands for deleting images and containers are different. docker rmi ID, where container (rm) and image (rmi).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Because the ID of the container is a random code, and the name of the container is a seemingly meaningless naming, we can use the command:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  docker rename  old_name new_name

  docker [stop] [start]  new_name // we can use new name now
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;List the images on the machine: docker images&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Pull down the image or repository from the docker registry server (pull), push an image or repository to the registry (push), corresponding to pull
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker pull centos:centos6 // Officical Image
docker pull username/repository&amp;lt;:tag_name&amp;gt; // Personal Image
docker pull seanlook/centos:centos6
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Use image to create a container and enter interactive mode, login shell is /bin/bash
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo docker run -it -h pbs –-name pbs -e PBS_START_MOM=1 pbspro/pbspro bash // -i: interactive mode, -t: allocate pseudo terminal, -h: give hostname, --name give a name;
sudo docker  --privileged -p 8817:6817 -p 8818:6818 --dns 8.8.8.8 --dns 8.8.4.4 -h controler --name slurm_control1  -i -t run ubuntu:16.04 /bin/bash
sudo docker run -h controler --name slurm_control1  -i -t ubuntu:16.04 /bin/bash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Mapping host to container port and directory: -p &lt;host_port:contain_port&gt;
&lt;/host_port:contain_port&gt;    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;-p 127.0.0.1:127.0.0.1:11211:11211 // Only bind port 11211 of the localhost interface
-p 11211:11211　// This is the default situation, binding the 11211 port of all network cards (0.0.0.0) of the host to the 11211 port of the container.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Solidify a container into a new image:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker commit &amp;lt;cotainer&amp;gt; [repo:tag]
docker commit -m &quot;some tools installed&quot; fcbd0a5348ca seanlook/ubuntu:14.10_tutorial
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;To install software in docker, you need apt update to install the software after entering the terminal. The container installed by Docker’s Ubuntu image does not have the ifconfig command and the ping command to solve the problem:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apt-get update
apt install net-tools       // ifconfig 
apt install iputils-ping     // ping
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Execute the command on the host machine to copy the file to docker
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker cp // The file path to be copied and the container name: must be assigned to the corresponding path in the container;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 07 Aug 2021 00:00:00 +0000</pubDate>
        <link>https://guangjing.wang/2021/08/07/server-setup-two/</link>
        <guid isPermaLink="true">https://guangjing.wang/2021/08/07/server-setup-two/</guid>
        
        <category>Docker</category>
        
        
        <category>System</category>
        
      </item>
    
      <item>
        <title>Server Setup (1)</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#gitlab&quot; id=&quot;markdown-toc-gitlab&quot;&gt;&lt;strong&gt;Gitlab&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#owncloud&quot; id=&quot;markdown-toc-owncloud&quot;&gt;&lt;strong&gt;ownCloud&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#ip-and-dns&quot; id=&quot;markdown-toc-ip-and-dns&quot;&gt;&lt;strong&gt;IP and DNS&lt;/strong&gt;&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#firewall&quot; id=&quot;markdown-toc-firewall&quot;&gt;&lt;strong&gt;Firewall&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#port&quot; id=&quot;markdown-toc-port&quot;&gt;&lt;strong&gt;Port&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#ssl&quot; id=&quot;markdown-toc-ssl&quot;&gt;&lt;strong&gt;SSL&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, my focus primarily revolves around documenting the procedure for setting up personal servers for ownCloud and Gitlab, aided by the plethora of valuable online resources and blogs available.&lt;/p&gt;

&lt;h3 id=&quot;gitlab&quot;&gt;&lt;strong&gt;Gitlab&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;GitLab uses Ruby on Rails, an open source version management system, to implement a self-hosted Git project warehouse that can access public or private projects through a web interface. It has similar functionality to Github, with the ability to browse source code and manage defects and comments. Installation reference link: &lt;a href=&quot;https://about.gitlab.com/installation/&quot;&gt;Gitlab&lt;/a&gt;. In fact, the installation process is relatively simple.&lt;/p&gt;

&lt;p&gt;Software integration is a link in the software development process. The work in this link generally includes the following processes: merge code—&amp;gt;install dependencies—&amp;gt;compile—&amp;gt;test—&amp;gt;release, software The integration work is detailed and tedious and was previously done manually. But now continuous integration is encouraged (continuous integration is a software development practice, that is, team development members integrate their work frequently, usually each member integrates at least once a day, and each integration is through an automated build), therefore, the continuous integration system should be And born.
GitLab-CI is a continuous integration system used with GitLab. Generally, each project in GitLab will define a software integration script belonging to this project to automatically complete some software integration work. When the warehouse code of this project changes, for example, someone pushes the code, GitLab will notify GitLab-CI of the change. At this time, GitLab-CI will find the Runners associated with this project and notify these Runners to update the code locally and execute the predefined execution script. Therefore, GitLab-Runner is a tool used to execute software integration scripts.&lt;/p&gt;

&lt;p&gt;In fact, in addition to Github and Gitlab, there is also Bitbucket as a code warehouse management.&lt;/p&gt;

&lt;h3 id=&quot;owncloud&quot;&gt;&lt;strong&gt;ownCloud&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;ownCloud is a tool used to create your own private cloud service, which can fully control the data and can be used within a pure LAN. It supports file preview, version control, link sharing, and can also load third-party storage, API support, and more. Both server and client are supported by all platforms. First, you need to install the LAMP suite; then install ownCoud and configure the database.&lt;/p&gt;

&lt;p&gt;Reference: &lt;a href=&quot;https://blog.csdn.net/And_w/article/details/71238266&quot;&gt;csdnblog&lt;/a&gt;  &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-owncloud-on-ubuntu-16-04&quot;&gt;digitalocean&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;ip-and-dns&quot;&gt;&lt;strong&gt;IP and DNS&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The network outside the school is really complicated. If you have a company IP, you can only apply for a fixed IP from the operator, otherwise it will be dynamic. You can use peanut shells or router domain names to bind dynamic IP, and then set up the DMZ host. Broadband external network IPs are displayed starting with 10, 100, and 172, and there is no public network IP. The reason is that under the current IPV4, public network IP as a non-renewable resource has been stretched, and there are more and more Internet users and Internet devices, so operators have It is impossible to provide sufficient IP address resources for new users, so operators can only use NAT forwarding technology (network address translation) to put some users in a large LAN and share a small number of external network exits, thereby alleviating IP pressure. , just like a community, you and all residents in the same community share a community gate. The solution is of course to file a complaint or spend more money to fix the IP.&lt;/p&gt;

&lt;h4 id=&quot;firewall&quot;&gt;&lt;strong&gt;Firewall&lt;/strong&gt;&lt;/h4&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo ufw app list　//registed a few profiles with ufw
sudo ufw status
sudo ufw allow &apos;Apache Full&apos;
sudo ufw delete allow &apos;Apache&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;port&quot;&gt;&lt;strong&gt;Port&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;One reason is to prevent hackers, and the other reason is that port 80 is blocked by email…&lt;/p&gt;

&lt;p&gt;For the Apache web server:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/apache2/ports.conf // change NameVirtualHost *:80 and Listen 80 to our own.
/etc/apache2/sites-available/default // change the VirtualHost :80 to our own e.g., VirtualHost :1000
/etc/init.d/apache2/httpd.conf // add servername localhost

sudo /etc/init.d/apache2 restart 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;ssl&quot;&gt;&lt;strong&gt;SSL&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;To implement https, you need an SSL certificate. Cloud service providers such as Tencent Cloud, Qiniu Cloud, and Alibaba Cloud, but most of them are very expensive. In line with the principle of saving money for the company, I found many ways to make my own certificate, because my 443 port was also blocked. This really made me cry.&lt;/p&gt;

&lt;p&gt;Later, I found a [method] for issuing let’s encrypt ssl certificate for non-port 80 that does not support Http verification domain name (https://blog.nbhao.org/2633.html). Finally, it is clear that our problem is to make a &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-apache- in-ubuntu-16-04&quot;&gt;self-signed SSL certificate&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
sudo nano /etc/apache2/conf-available/ssl-params.conf
sudo a2enmod ssl
sudo a2enmod headers
sudo a2ensite default-ssl
sudo a2enconf ssl-params
sudo apache2ctl configtest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A new interesting probelm: ERR_SSL_PROTOCOL_ERROR when accessing this server. &lt;a href=&quot;https://stackoverflow.com/questions/34304022/change-ssl-port-of-apache2-server-err-ssl-protocol-error&quot;&gt;Soultion reference&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;I summarize all procedures to set up ssl and changing its port. In this example, I change ssl port to 18443 from 443.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get install apache2
sudo a2enmod ssl
sudo a2ensite default-ssl
sudo service apache2 restart
ss -lnt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then, trying to change ssl port:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo vi /etc/apache2/ports.conf
&amp;lt;IfModule ssl_module&amp;gt;
        Listen 18443
&amp;lt;/IfModule&amp;gt;
&amp;lt;IfModule mod_gnutls.c&amp;gt;
        Listen 18443
&amp;lt;/IfModule&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In this setting, I use default-ssl, so I also have to modify this file.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo vi /etc/apache2/sites-available/default-ssl.conf
 &amp;lt;IfModule mod_ssl.c&amp;gt;
   &amp;lt;VirtualHost _default_:18443&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Sun, 01 Aug 2021 00:00:00 +0000</pubDate>
        <link>https://guangjing.wang/2021/08/01/server-setup-one/</link>
        <guid isPermaLink="true">https://guangjing.wang/2021/08/01/server-setup-one/</guid>
        
        <category>ownCloud</category>
        
        <category>Gitlab</category>
        
        
        <category>System</category>
        
      </item>
    
      <item>
        <title>Android Notes</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#basic-java&quot; id=&quot;markdown-toc-basic-java&quot;&gt;&lt;strong&gt;Basic Java&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#sensors&quot; id=&quot;markdown-toc-sensors&quot;&gt;&lt;strong&gt;Sensors&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some notes about Android Development. I have taken “CSE 476 Mobile Application Development” at MSU, but to avoid leaking course materials, I will just keep them in my mind &lt;em&gt;HOPEFULLY&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id=&quot;basic-java&quot;&gt;&lt;strong&gt;Basic Java&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;JNI: Java Native Interface, which is a feature of Java，making Jave interacts with other programming languages; For example, Java calls C++; C++ calls Java.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;NDK: Native Development Kit, which helps to develop C++ dynamic library and automatically package shared libraries and applications into APKs．&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Android.mk formulates the configuration information for source code compilation, and Application.mk configures the relevant content of the compilation platform;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;sensors&quot;&gt;&lt;strong&gt;Sensors&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Location: longitude, latitude, and altitude&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Accelerometer: gravity and linear accelerometer&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Gyroscope: measuring the rotation speed of the device, mostly required for games like 3D racing&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Proximity: check whether there is some obstacle at a very close distance to your device.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Orientation: magnetic field force in 3-axis space, z is related to the magnetic north pole(0 means the top of your phone points to the north pole), x is related to the ground (90 means the phone is standing vertically), y shows roll (0 means the phone is facing to the sky, 180 means the screen is facing the ground).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 22 Aug 2020 00:00:00 +0000</pubDate>
        <link>https://guangjing.wang/2020/08/22/android-notes/</link>
        <guid isPermaLink="true">https://guangjing.wang/2020/08/22/android-notes/</guid>
        
        <category>Android</category>
        
        <category>Sensor</category>
        
        
        <category>System</category>
        
      </item>
    
      <item>
        <title>Celery Notes</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#producer-consumer&quot; id=&quot;markdown-toc-producer-consumer&quot;&gt;&lt;strong&gt;Producer-Consumer&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#celery-with-django&quot; id=&quot;markdown-toc-celery-with-django&quot;&gt;&lt;strong&gt;Celery with Django&lt;/strong&gt;&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#add-task&quot; id=&quot;markdown-toc-add-task&quot;&gt;&lt;strong&gt;Add Task&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#periodic-tasks&quot; id=&quot;markdown-toc-periodic-tasks&quot;&gt;&lt;strong&gt;Periodic Tasks&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Celery is a distributed system to process vast amounts of messages while providing operations with the tools requires to maintain such a system. It is a task queue with a focus on real-time processing, while also supporting task scheduling.&lt;/p&gt;

&lt;p&gt;Celery architecture consists of three parts: message broker, worker and task result store. Before operating celery in detail, let’s introduce a few concepts.&lt;/p&gt;

&lt;h3 id=&quot;producer-consumer&quot;&gt;&lt;strong&gt;Producer-Consumer&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The producer is the module responsible for generating data; the consumer is the module responsible for processing data. The broker acts as a buffer between the producer and the consumer. The producer puts the data into the buffer, and the consumer takes the data out of the buffer; this buffer plays the role of “decoupling”;&lt;/p&gt;

&lt;p&gt;In asynchronous communication, the message will not reach the receiver immediately but will be stored in a container. When certain conditions are met, the message will be sent to the receiver by the container. This container is the message queue. To complete this function, both parties and the container are required to abide by the unified conventions and rules. AMQP (advanced message queuing protocol) is such a protocol, and RabbitMQ is a message-queuing product based on AMQP.&lt;/p&gt;

&lt;p&gt;The main elements included in AMQP: are the producer publishes the message; the consumer obtains the message from the message queue; the message queue is used to save the message. The exchanger is the routing component that accepts the message sent by the producer and forwards the message route to the message queue; The virtual host is a collection of switches, message queues, and related objects. A channel is an independent bidirectional data flow channel in a multiplexed connection, providing a physical transmission medium for a session.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;publisher--publish--&amp;gt;exchange--routes--&amp;gt;queue--consume--&amp;gt;consumer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;celery-with-django&quot;&gt;&lt;strong&gt;Celery with Django&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://docs.celeryproject.org/en/latest/&quot;&gt;Celery Reference&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;celery -A petct worker -l info --pidfile id.txt 
# The --pidfile argument can be set to an absolute path to avoid  having other old workers still running.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;add-task&quot;&gt;&lt;strong&gt;Add Task&lt;/strong&gt;&lt;/h4&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# tasks.py

from __future__ import absolute_import, unicode_literals
from celery import shared_task
from celery.decorators import task
from celery.utils.log import get_task_logger
from .draw3d import loadArray

logger = get_task_logger(__name__)

@shared_task(name=&quot;loadArray&quot;)
def loadArray_task(filepath, shape):
    logger.info(&quot;load 3d array&quot;)
    return loadArray(filepath, shape)



# views.py

from .tasks import loadArray_task

def show(request):
    if request.method == &apos;GET&apos;:
        filePos=request.GET.get(&quot;userID&quot;, None)
        record=Record.objects.get(userID=filePos)

        global mydict
        if filePos not in mydict:
            loadtask=loadArray_task.delay(&quot;./file.mpv&quot;, (110,110,187))
            mydict[filePos]=loadtask.get(timeout=1)

        return render(request, &apos;show.html&apos;, {&apos;record&apos;: record})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;periodic-tasks&quot;&gt;&lt;strong&gt;Periodic Tasks&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Scheduling a task to run at a specific time, &lt;a href=&quot;https://realpython.com/asynchronous-tasks-with-django-and-celery/&quot;&gt;Refer&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# tasks.py
# we run the save_latest_flickr_image() function every fifteen minutes by wrapping the function call in a task. 

from celery.task.schedules import crontab
from celery.decorators import periodic_task
from celery.utils.log import get_task_logger

from photos.utils import save_latest_flickr_image

logger = get_task_logger(__name__)

@periodic_task(
    run_every=(crontab(minute=&apos;*/15&apos;)),
    name=&quot;task_save_latest_flickr_image&quot;,
    ignore_result=True
)
def task_save_latest_flickr_image():
    &quot;&quot;&quot;
    Saves latest image from Flickr
    &quot;&quot;&quot;
    save_latest_flickr_image()
    logger.info(&quot;Saved image from Flickr&quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can also run the job remotely using &lt;em&gt;Supervisor&lt;/em&gt;. We need to tell Supervisor about our Celery workers by adding configuration files to the “/etc/supervisor/conf.d/” directory on the remote server. In our case, we need two such configuration files - one for the Celery worker and one for the Celery scheduler.&lt;/p&gt;
</description>
        <pubDate>Sun, 09 Aug 2020 00:00:00 +0000</pubDate>
        <link>https://guangjing.wang/2020/08/09/celery-notes/</link>
        <guid isPermaLink="true">https://guangjing.wang/2020/08/09/celery-notes/</guid>
        
        <category>Celery</category>
        
        <category>RabbitMQ</category>
        
        
        <category>System</category>
        
      </item>
    
      <item>
        <title>Redis Notes</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#scenarios&quot; id=&quot;markdown-toc-scenarios&quot;&gt;&lt;strong&gt;Scenarios&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#installation&quot; id=&quot;markdown-toc-installation&quot;&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#advanced&quot; id=&quot;markdown-toc-advanced&quot;&gt;&lt;strong&gt;Advanced&lt;/strong&gt;&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#deletion&quot; id=&quot;markdown-toc-deletion&quot;&gt;&lt;strong&gt;Deletion&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#breakdown&quot; id=&quot;markdown-toc-breakdown&quot;&gt;&lt;strong&gt;Breakdown&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#cons&quot; id=&quot;markdown-toc-cons&quot;&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#python-with-redis&quot; id=&quot;markdown-toc-python-with-redis&quot;&gt;&lt;strong&gt;Python with Redis&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Redis is an in-memory data structure store, used as a database, cache, and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries, and streams.&lt;/p&gt;

&lt;p&gt;Redis supports data persistence. It can save data in memory to disk and load it again for use when restarting. Redis not only supports simple key-value type data, but also provides string, list, set, and zset. , storage of data structures such as hash; Redis supports data backup, that is, data backup in master-slave mode; all operations of Redis are atomic, either executed successfully or not executed at all if failed.&lt;/p&gt;

&lt;h3 id=&quot;scenarios&quot;&gt;&lt;strong&gt;Scenarios&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;(1) Cache data, for data that needs to be queried frequently and changes infrequently (hot data);&lt;/p&gt;

&lt;p&gt;(2) Used as a message queue, equivalent to a message subscription system;&lt;/p&gt;

&lt;p&gt;(3) As a counter, count click rate, like rate, etc., because redis is atomic and can avoid concurrency problems;&lt;/p&gt;

&lt;p&gt;Why is Redis so fast? Pure memory operation (can be manually persisted to the hard disk), single thread (avoiding frequent context switching operations in multi-threads), the data structure and operation are relatively simple, redis has established its own VM mechanism in the underlying model, because of general system calls For system functions, a certain amount of time will be wasted to move and request, so use a multi-channel I/O multiplexing model and a non-blocking model.&lt;/p&gt;

&lt;h3 id=&quot;installation&quot;&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install redis-server

redis-server --maxclients 100000 #start redis, set maximum connections

redis-cli # Connect to local redis service 
redis-cli -h host -p port -a password # Execute commands on the remote redis service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;String is the most basic type of redis. One key corresponds to one value. It is binary safe and can contain any data, such as pictures or serialized objects. Redis hash is a set of key-value (key=&amp;gt;value) pairs. Hash is particularly suitable for storing objects. For example, it can be used to store user IDs, avatar points, etc. in forum systems. If you want to modify the information, you only need to retrieve it through the key. Value is deserialized to modify the value of one of the items, and then serialized and stored in Redis. Redis list is sorted in insertion order. You can add an element to the head (left) or tail (right) of the list. Set is an unordered collection of string type, implemented through a hash table. Addition, deletion, and search complexity are all O(1).&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;SET string_name &quot;runoob&quot;
GET string_name

HMSET myhash key_field1 &quot;Hello&quot; key_field2 &quot;World&quot;
HGET myhash key_field1

lpush list_runoob redis
lrange list_runoob 0 10

sadd set_runoob redis
smembers set_runoob

zadd key score member 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Redis HyperLogLog&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Data set {1, 3, 5, 7, 5, 7, 8}, then the cardinality set of this data set is {1, 3, 5,7, 8}, and the cardinality (non-repeating elements) is 5. Cardinality estimation is to quickly calculate the cardinality within the acceptable error range. Redis HyperLogLog is an algorithm used for cardinality statistics. When the number or volume of input elements is very large, the space required to calculate the cardinality is always fixed and very small.&lt;/p&gt;

&lt;h3 id=&quot;advanced&quot;&gt;&lt;strong&gt;Advanced&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Redis publish and subscribe (pub/sub) is a message communication model: the sender (pub) sends messages and the subscriber (sub) receives messages:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;SUBSCRIBE redisChat
PUBLISH redisChat &quot;Learn redis by runoob.com&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Redis transactions can execute multiple commands at one time. Batch operations are put into the queue cache before sending the EXEC command. After receiving the EXEC command, transaction execution is entered. If any command in the transaction fails to execute, the remaining commands are still executed. During transaction execution, command requests submitted by other clients will not be inserted into the transaction execution command sequence.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;MULTI # start transaction
SET book-name &quot;Mastering C++ in 21 days&quot;　# command to queue
SADD tag &quot;C++&quot; &quot;Programming&quot; &quot;Mastering Series&quot;　# command to queue
EXEC　# execute transaction
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The Redis SAVE command is used to create a backup of the current database; BGSAVE, this command is executed in the background; if you need to restore data, just move the backup file (dump.rdb) to the redis installation directory and start the service.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CONFIG GET dir # get file directory
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;deletion&quot;&gt;&lt;strong&gt;Deletion&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;The default is to detect once every 100ms. If an expired key is encountered, it will be deleted. Random detection is used here. In order to prevent the fish from slipping through the net, when we read and write an expired key, the lazy deletion strategy of redis will be triggered. Directly Expired keys will be deleted.&lt;/p&gt;

&lt;h4 id=&quot;breakdown&quot;&gt;&lt;strong&gt;Breakdown&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Caching is a layer of protection added to relieve the pressure on the database. When the data we need cannot be queried from the cache, we must query the database. If hackers use it to frequently access data that does not exist in the cache, the cache will lose its meaning. , causing database connection exception;&lt;/p&gt;

&lt;p&gt;Solution:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Set up scheduled tasks in the background and actively update cached data;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Hierarchical cache, for example, setting up two cache protection layers. The first-level cache has a short expiration time, and the second-level cache has a long expiration time. When a request comes, priority is given to searching from the first-level cache. If the corresponding data is not found in the first-level cache, Then the thread is locked, and this thread gets the data from the database, updates the level 1 and level 2 caches, and other threads get it directly from the level 2 cache.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Provide an interception mechanism that internally maintains a series of legal key values. When the requested key is illegal, it will be returned directly.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;cons&quot;&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Since Redis is an in-memory database, the amount of data stored in a single machine is limited, and unnecessary data needs to be deleted in time. After modifying the redis data, the data persisted to the hard disk needs to be re-added to the memory, which takes a long time. redis cannot run normally.&lt;/p&gt;

&lt;h3 id=&quot;python-with-redis&quot;&gt;&lt;strong&gt;Python with Redis&lt;/strong&gt;&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import redis
r = redis.Redis(host=&apos;192.168.0.110&apos;, port=6379,db=0)

pool = redis.ConnectionPool(host=&apos;192.168.0.110&apos;, port=6379)
r = redis.Redis(connection_pool=pool)

pipe = r.pipeline(transaction=True) # use pipline to specify multiple commands in one request

r.set(&apos;name&apos;, &apos;zhangsan&apos;)
r.mset(name1=&apos;zhangsan&apos;, name2=&apos;lisi&apos;)

r.hset(&quot;dic_name&quot;,&quot;a1&quot;,&quot;aa&quot;)　# name, key, value
r.hget(&quot;dic_name&quot;,&quot;a1&quot;)

r.lpush(name,values)
r.rpush(name,values)
r.lpop(name)

r.sadd(name,values)

r.zadd(&quot;zset_name&quot;, &quot;a1&quot;, 6, &quot;a2&quot;, 2,&quot;a3&quot;,5)

class RedisHelper(object):
    def __init__(self):
        self.__conn = redis.Redis(host=&apos;192.168.0.110&apos;,port=6379)
        self.channel = &apos;monitor&apos;

    def publish(self,msg):
        self.__conn.publish(self.channel,msg)
        return True

    def subscribe(self):
        pub = self.__conn.pubsub()
        pub.subscribe(self.channel)
        pub.parse_response()
        return pub

from RedisHelper import RedisHelper

obj = RedisHelper()
obj.publish(&apos;hello&apos;)

obj = RedisHelper()
redis_sub = obj.subscribe()

while True:
    msg= redis_sub.parse_response()
    print (msg)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Sat, 25 Jul 2020 00:00:00 +0000</pubDate>
        <link>https://guangjing.wang/2020/07/25/redis-notes/</link>
        <guid isPermaLink="true">https://guangjing.wang/2020/07/25/redis-notes/</guid>
        
        <category>Redis</category>
        
        
        <category>System</category>
        
      </item>
    
      <item>
        <title>Django Notes</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#django-introduction&quot; id=&quot;markdown-toc-django-introduction&quot;&gt;&lt;strong&gt;Django Introduction&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#reset-django-migration&quot; id=&quot;markdown-toc-reset-django-migration&quot;&gt;&lt;strong&gt;Reset Django migration&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#django-admin&quot; id=&quot;markdown-toc-django-admin&quot;&gt;&lt;strong&gt;Django admin&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#django-view&quot; id=&quot;markdown-toc-django-view&quot;&gt;&lt;strong&gt;Django View&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#ui-in-chinese&quot; id=&quot;markdown-toc-ui-in-chinese&quot;&gt;&lt;strong&gt;UI in Chinese&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#jquery&quot; id=&quot;markdown-toc-jquery&quot;&gt;&lt;strong&gt;jQuery&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#others&quot; id=&quot;markdown-toc-others&quot;&gt;&lt;strong&gt;Others&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Django, a Python web framework known for its emphasis on swift development, has prompted me to jot down some notes during my Django usage. Additionally, I have taken notes on JQuery.&lt;/p&gt;

&lt;h3 id=&quot;django-introduction&quot;&gt;&lt;strong&gt;Django Introduction&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Django is an MVC model: (i) M means Model, which defines the database-related content and is placed in the model.py file. (ii) V means View, which defines the front-end related to the static web pages such as HTML; (iii) C means Controller, which defines the processing logic in the view.py file. A Django project can have multiple apps, which can be regarded as sub-systems/sub-modules in a large-scale project. These apps can be independent but could be related.&lt;/p&gt;

&lt;h3 id=&quot;reset-django-migration&quot;&gt;&lt;strong&gt;Reset Django migration&lt;/strong&gt;&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Delete all migrations, and then delete the database:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;find . -path &quot;*/migrations/*.py&quot; -not -name &quot;__init__.py&quot; -delete
find . -path &quot;*/migrations/*.pyc&quot;  -delete
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Re-generate migrations
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python manage.py makemigrations
python manage.py migrate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;django-admin&quot;&gt;&lt;strong&gt;Django admin&lt;/strong&gt;&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class showAdmin(admin.ModelAdmin):
    list_display = (&apos;userID&apos;, &apos;name&apos;, &apos;taskID&apos;, &apos;status&apos;, &apos;createTime&apos;, &apos;is_sure&apos;, &apos;show_firm_url&apos;,)
    search_fields = (&apos;name&apos;,)
    list_display_links = (&apos;userID&apos;, &apos;status&apos;)

    def show_firm_url(self, obj):
        return format_html(&quot;&amp;lt;a href=&apos;{url}&apos;&amp;gt;Download&amp;lt;/a&amp;gt;&quot;, url=&quot;/mtasks/download/&quot;)
    show_firm_url.short_description = &quot;Results&quot;

    def get_readonly_fields(self, request, obj=None):
        if hasattr(obj, &apos;is_sure&apos;):
            if obj.is_sure:
                self.readonly_fields = (&apos;is_sure&apos;, &apos;userID&apos;, &apos;name&apos;, &apos;taskID&apos;, &apos;status&apos;)
        else:
            self.readonly_fields = (&apos;userID&apos;, &apos;taskID&apos;, &apos;status&apos;)
        return self.readonly_fields
 
    def change_view(self, request, object_id, form_url=&apos;&apos;, extra_context=None):
        change_obj = self.model.objects.filter(pk=object_id)
        self.get_readonly_fields(request, obj=change_obj)
        return super(showAdmin, self).change_view(request, object_id, form_url, extra_context=extra_context)

    def save_model(self, request, obj, form, change):
    def delete_model(self, request, obj):
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;django-view&quot;&gt;&lt;strong&gt;Django View&lt;/strong&gt;&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;def get_pic(request):
    if request.method == &apos;POST&apos;:
        fileID=request.POST.get(&quot;fileID&quot;)
        foldPath=&apos;results/&apos;+str(fileID)+&apos;/&apos;
        if not os.path.exists(settings.PICTURE_URL+fileID+&quot;snap_x.gif&quot;):
            drawGIF(foldPath+&apos;voxel_0_subset_0.mpv&apos;, &apos;x&apos;, fileID)
            drawGIF(foldPath+&apos;voxel_0_subset_0.mpv&apos;, &apos;y&apos;, fileID)
            drawGIF(foldPath+&apos;voxel_0_subset_0.mpv&apos;, &apos;z&apos;, fileID)
        pic1=fileID+&quot;snap_x.gif&quot;;
        pic2=fileID+&quot;snap_y.gif&quot;;
        pic3=fileID+&quot;snap_z.gif&quot;;
        data=[pic1, pic2, pic3]
        return HttpResponse(json.dumps(data), content_type=&apos;application/json&apos;)
// In url.py 
urlpatterns += static(&apos;mtasks/download/&apos;, document_root=settings.PICTURE_ROOT)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;ui-in-chinese&quot;&gt;&lt;strong&gt;UI in Chinese&lt;/strong&gt;&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;SITE_HEADER = os.environ.get(&apos;SITE_HEADER&apos;, &apos;Management System&apos;) //setting.py
admin.AdminSite.site_header =&apos;Management System&apos;　//admin.py
admin.AdminSite.site_title = &apos;Management Platform&apos; //admin.py
// models.py
class Meta:
        verbose_name=&quot;Task&quot;  //verbose_name can be used for naming table attributes
        verbose_name_plural=&quot;Task&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;jquery&quot;&gt;&lt;strong&gt;jQuery&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Js is a front-end script, and we can use ajax (Asynchronous Javascript and XML) to make the back-end server call python script, and then return results to the front end.jQuery is one of the frameworks of javascript, and jQuery uses ‘$’ as the abbreviation of jQuery.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$(selector).action() //$ defines jQuery;
$(“#test”).hide() //hide all elements with id=”test”;

// To prevent the running of the jQuery code before the full loading of the document.
$(document).ready(function(){
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;load() means loading data from the server and then returning the data to the selected element;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$(selector).load(URL, data, callback);&lt;/code&gt;
    &lt;ul&gt;
      &lt;li&gt;The required URL parameter specifies the URL to be loaded.&lt;/li&gt;
      &lt;li&gt;The optional data parameter specifies the set of the query string (in key-value pairs) sent with the request;&lt;/li&gt;
      &lt;li&gt;The optional callback is the name of the function to be executed after the load() method completes;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;post() method request to load data from the server with HTTP POST &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$.post(URL, data, callback);&lt;/code&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$.post(URL, data, success(data, testStatus, jqXHR), dataType) &lt;/code&gt;
    &lt;ul&gt;
      &lt;li&gt;The URL is the address that the request is sent;&lt;/li&gt;
      &lt;li&gt;The data can be sent with the request, optional;&lt;/li&gt;
      &lt;li&gt;The success() is the callback function after the data is loaded.&lt;/li&gt;
      &lt;li&gt;dataType() is the expected type of data from the server.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;$.get(url, callback); GET-requesting data from the specified location; POST-sending the data to the specified resources and then requesting data.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;$(selector).each(function(index, element)) Specifing the function to run for each matched element.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;others&quot;&gt;&lt;strong&gt;Others&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;The decorator @route() can bind a function to the corresponding URL; instead of accessing the index page, the user can directly access the desired page.&lt;/li&gt;
  &lt;li&gt;Passing parameters with “?” &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://127.0.0.1:8000/plist/?p1=china&amp;amp;p2=2012&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Show pictures with Django &lt;a href=&quot;https://www.cnblogs.com/zhawj159753/p/3938134.html&quot;&gt;Reference&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Monitoring the event:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;event.target //return the DOM element
event.target.id
event.target.nodeName
event.target.innerHTML //return the content of the DOM
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Example
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
  $(document).ready(function(){
    var ide=document.getElementsByName(&quot;myUser&quot;);
    for (var i=0; i&amp;lt;ide.length; i++){

        $(&quot;#&quot;+ide[i].innerHTML).click(function(event){
        url = &quot;/get_pic/&quot;;
        alert(&quot;Drawing&quot;)
        $.post(url, {&quot;fileID&quot;:event.target.id}, success, &quot;json&quot;);

        function success(data){
          $(&apos;#result_x&apos;).html(&apos;&apos;)
          $(&apos;#result_y&apos;).html(&apos;&apos;)
          $(&apos;#result_z&apos;).html(&apos;&apos;)

          $(&apos;#result_x&apos;).append(&apos;&amp;lt;img src=&apos;+data[0] +&apos; alt=&quot;Lights&quot; style=&quot;width:100%&quot;&amp;gt;&apos;);
          $(&apos;#result_y&apos;).append(&apos;&amp;lt;img src=&apos;+data[1] +&apos; alt=&quot;Lights&quot; style=&quot;width:100%&quot;&amp;gt;&apos;);
          $(&apos;#result_z&apos;).append(&apos;&amp;lt;img src=&apos;+data[2] +&apos; alt=&quot;Lights&quot; style=&quot;width:100%&quot;&amp;gt;&apos;);
        }
      });
    } 
  });
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 18 Jul 2020 00:00:00 +0000</pubDate>
        <link>https://guangjing.wang/2020/07/18/django-notes/</link>
        <guid isPermaLink="true">https://guangjing.wang/2020/07/18/django-notes/</guid>
        
        <category>Django</category>
        
        
        <category>System</category>
        
      </item>
    
      <item>
        <title>TensorFlow Notes</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#main-changes&quot; id=&quot;markdown-toc-main-changes&quot;&gt;&lt;strong&gt;Main Changes&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#using-gpu&quot; id=&quot;markdown-toc-using-gpu&quot;&gt;&lt;strong&gt;Using GPU&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#training-step&quot; id=&quot;markdown-toc-training-step&quot;&gt;&lt;strong&gt;Training step&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#custom-layer&quot; id=&quot;markdown-toc-custom-layer&quot;&gt;&lt;strong&gt;Custom Layer&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#custom-model&quot; id=&quot;markdown-toc-custom-model&quot;&gt;&lt;strong&gt;Custom Model&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#basics-for-10&quot; id=&quot;markdown-toc-basics-for-10&quot;&gt;&lt;strong&gt;Basics for 1.0&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#optimization&quot; id=&quot;markdown-toc-optimization&quot;&gt;&lt;strong&gt;Optimization&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#save-model&quot; id=&quot;markdown-toc-save-model&quot;&gt;&lt;strong&gt;Save Model&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#load-model&quot; id=&quot;markdown-toc-load-model&quot;&gt;&lt;strong&gt;Load Model&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TensorFlow is an open source software library for high performance numerical computation, and it is developed into TF2.0. Here I add some new notes about tensorflow new features, for more details, you can refer to the official &lt;a href=&quot;https://www.tensorflow.org/&quot;&gt;website&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;main-changes&quot;&gt;&lt;strong&gt;Main Changes&lt;/strong&gt;&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;In TF2.0, the eager execution dynamic graph is used by default in TF2.0, and the calculation will be executed directly. If we need to build a static computation graph, we only need to add the @tf.function decorator to the python function. An important change in TF2 is to remove tf.Session(). The more complex the computation graph is, the more execution efficiency and acceleration effect of using static graphs.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The tool that converts python code into graph representation code is called autoGraph. If a function is decorated with @tf.function, then autoGraph will be called automatically, thus converting the python function into a static executable graph representation.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;When the function decorated with @tf.function is called for the first time, the function is executed and tracked, eager will be disabled in this function, so each tf.API will only define one to generate tf.Tensor output node.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;When using tf.function, you need to check if the function is feasible in a static graph when converting a dynamic graph into a static graph. In a dynamic graph, tf.variable is an ordinary python variable. It will be destroyed beyond its scope. In the static graph, tf.valuable is a persistent node in the calculation graph, which is not affected by the scope of python. We can use tf.variable as a parameter of the function Pass in, call tf.variable as a class attribute.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(1) Every tf.Session.run call should be replaced by a Python function.
    The feed_dict and tf.placeholders become function arguments.
    The fetches become the function&apos;s return value.
(2) Use tf.Variable instead of tf.get_variable.
(3) Prefer tf.keras.Model.fit over building your own training loops.
(4) Use tf.data datasets for data input.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import tensorflow_datasets as tfds
datasets, info = tfds.load(name=&apos;mnist&apos;, with_info=True, as_supervised=True)
mnist_train, mnist_test = datasets[&apos;train&apos;], datasets[&apos;test&apos;]
def scale(image, label):
    image = tf.cast(image, tf.float32)
    image /= 255
    return image, label
train_data = mnist_train.map(scale).shuffle(BUFFER_SIZE).batch(BATCH_SIZE).take(5)
test_data = mnist_test.map(scale).batch(BATCH_SIZE).take(5)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;using-gpu&quot;&gt;&lt;strong&gt;Using GPU&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;We can specify the running device by tf.device(). For example, “/cpu:0” is the cpu of your machine, “/device:GPU:0”:The first GPU of your machine, “/device:GPU:1”:The second GPU of your machine.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# specify in code, or you can set when you run the python file
import os
os.environ[&quot;CUDA_VISIBLE_DEVICES&quot;] = &quot;2&quot;

# allocate gpu according to its need
config = tf.ConfigProto()
config.gpu_options.allow_growth = True

# specifiy GPU memory fraction
config.gpu_options.per_process_gpu_memory_fraction = 0.4

# TF2.0
gpus = tf.config.experimental.list_physical_devices(&apos;GPU&apos;)
if gpus:
    for gpu in gpus:
      tf.config.experimental.set_memory_growth(gpu, True)

gpus = tf.config.experimental.list_physical_devices(&apos;GPU&apos;)
if gpus:
    tf.config.experimental.set_visible_devices(gpus[0], &apos;GPU&apos;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;training-step&quot;&gt;&lt;strong&gt;Training step&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;If you need more flexibility and control, you can have it by implementing your own training loop. There are three steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Iterate over a Python generator or tf.data.Dataset to get batches of examples.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Use tf.GradientTape to collect gradients.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Use a tf.keras.optimizer to apply weight updates to the model’s variables.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Calling minimize() takes care of both computing the gradients and applying them to the variables. If you want to process the gradients before applying them you can instead use the optimizer in three steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Compute the gradients with tape.gradient().&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Process the gradients as you wish.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Apply the processed gradients with apply_gradients().&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation=&apos;relu&apos;,
                           kernel_regularizer=tf.keras.regularizers.l2(0.02),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation=&apos;relu&apos;),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10, activation=&apos;softmax&apos;)
])

optimizer = tf.keras.optimizers.Adam(0.001)
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy()

# Create the metrics
loss_metric = tf.keras.metrics.Mean(name=&apos;train_loss&apos;)
accuracy_metric = tf.keras.metrics.SparseCategoricalAccuracy(name=&apos;train_accuracy&apos;)

@tf.function
def train_step(inputs, labels):
    with tf.GradientTape() as tape:
      predictions = model(inputs, training=True)
      regularization_loss = tf.math.add_n(model.losses)
      pred_loss = loss_fn(labels, predictions)
      total_loss = pred_loss + regularization_loss

    gradients = tape.gradient(total_loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    # Update the metrics
    loss_metric.update_state(total_loss)
    accuracy_metric.update_state(labels, predictions)


for epoch in range(NUM_EPOCHS):
    # Reset the metrics
    loss_metric.reset_states()
    accuracy_metric.reset_states()

    for inputs, labels in train_data:
      train_step(inputs, labels)
    # Get the metric results
    mean_loss = loss_metric.result()
    mean_accuracy = accuracy_metric.result()

    print(&apos;Epoch: &apos;, epoch)
    print(&apos;  loss:     {:.3f}&apos;.format(mean_loss))
    print(&apos;  accuracy: {:.3f}&apos;.format(mean_accuracy))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;custom-layer&quot;&gt;&lt;strong&gt;Custom Layer&lt;/strong&gt;&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class MyDenseLayer(tf.keras.layers.Layer):
    def __init__(self, num_outputs):
      super(MyDenseLayer, self).__init__()
      self.num_outputs = num_outputs
    
    def build(self, input_shape):
      self.kernel = self.add_variable(&quot;kernel&quot;, shape=[int(input_shape[-1]), self.num_outputs])
    
    def call(self, input):
      return tf.matmul(input, self.kernel)
  
layer = MyDenseLayer(10)
print(layer(tf.zeros([10, 5])))
print(layer.trainable_variables)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;custom-model&quot;&gt;&lt;strong&gt;Custom Model&lt;/strong&gt;&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class MNISTModel(Model):
    def __init__(self):
        super(MNISTModel, self).__init__()
        self.conv1 = Conv2D(32, 3, activation=&apos;relu&apos;)
        self.flatten = Flatten()
        self.d1 = Dense(128, activation=&apos;relu&apos;)
        self.d2 = Dense(10, activation=&apos;softmax&apos;)

    def call(self, x):
        x = self.conv1(x)
        x = self.flatten(x)
        x = self.d1(x)
        return self.d2(x)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;basics-for-10&quot;&gt;&lt;strong&gt;Basics for 1.0&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;It is still possible to run 1.X code, unmodified (except for contrib), in TensorFlow 2.0:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

The tf.layers module is used to contain layer-functions that relied on tf.variable_scope to define and reuse variables.
If you were using regularizers of initializers from tf.contrib, these have more argument changes than others.
# replace tf.contrib.layers.
tf.keras.layers.Conv2D(32, 3, activation=&apos;relu&apos;, kernel_regularizer=tf.keras.regularizers.l2(0.04), input_shape=(28, 28, 1))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import tensorflow as tf

x=tf.placeholder(tf.float32, shape=...)
y=tf.variable(0, name=&apos;x&apos;, dtype=tf.float32)
z=tf.constant(2.0, shape=..., dtype=...)
w=tf.get_variable(&apos;w&apos;, [1,2,3], initializer=tf.contrib.layers.xavier_initializer(seed=0))

tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=True, data_format=&apos;NHWC&apos;, dilations=[1, 1, 1, 1], name=None)

tf.nn.max_pool(value, ksize=[1,f,f,1], strides=[1,s,s,1], padding, data_format=&apos;NHWC&apos;, name=None) #ksize: kernel size, a window of size(f,f), stride of size(s,s)

tf.contrib.layers.flatten(inputs, outputs_collections=None, scope=None) # input is a tensor of size[batch_size,...], return a flattened tensor with shape [batch_size, k].

tf.contrib.layers.fully_connected(
    inputs,
    num_outputs,
    activation_fn=tf.nn.relu,
    normalizer_fn=None,
    normalizer_params=None,
    weights_initializer=initializers.xavier_initializer(),
    weights_regularizer=None,
    biases_initializer=tf.zeros_initializer(),
    biases_regularizer=None,
    reuse=None,
    variables_collections=None,
    outputs_collections=None,
    trainable=True,
    scope=None
) # fully_connected creates a variable called weights, representing a fully connected weight matrix, which is multiplied by the inputs to produce a Tensor of hidden units, returns the tensor variable representing the result of the series of operations. The input is a tensor of at least rank 2 and static value for the last dimension; i.e. [batch_size, depth], [None, None, None, channels]


tf.nn.softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, dim=-1, name=None)

tf.math.reduce_mean(input_tensor, axis=None, keepdims=None, name=None, reduction_indices=None, keep_dims=None) #Reduces input_tensor along the dimensions given in axis, if keepdims is true, the reduced dimensions are retained with length 1.

tf.reshape(x, [-1, 28, 28, 1])
tf.split(x,n,0) #ｘ is the Tensor to split, n is the number of splits, 0 is the dimension along which to split.

tf.nn.depthwise_conv2d(input, filter, strides, padding, rate=None, name=None, data_format=None) # Must have strides = [1, stride, stride, 1], Given a 4D input tensor and a filter tensor of shape [filter_height, filter_width, in_channels, channel_multiplier], containing in_channels convolutional filters of depth 1, depthwise_conv2d applies a different filter to each input channel (expanding from 1 channel to channel_multiplier channels for each), then concatenates the results together. The output has in_channels * channel_multiplier channels.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;optimization&quot;&gt;&lt;strong&gt;Optimization&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Gradient Descent: taking gradient step with respect to all m examples on each step&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Stochastic GD: using only 1 training examples before updating the gradients&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Minibatch GD: using a small part of examples&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Momentum: taking into account the past gradients to smooth out the update, and storing the direction of the previous gadients.This will be the exponentially weighted average of gradient on previous steps.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Adam: combing ideas from RMSProp and Momentum.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;save-model&quot;&gt;&lt;strong&gt;Save Model&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;checkpoints is a binary file，which mapping variables into corresponding tensors．&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;saver=tf.train.Saver(...variables...)
sess = tf.Session()
for step in xrange(1000000):
    sess.run(..training_op..)
    if step % 1000 == 0:
        # Append the step number to the checkpoint name:
        saver.save(sess, &apos;my-model&apos;, global_step=step)   #  ==&amp;gt; filename: &apos;my-model-[step]&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;tf.app.flags get parameters from the coommand line:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_float(&apos;learning_rate&apos;, 0.01, &apos;Initial learning rate.&apos;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;From &lt;a href=&quot;https://stackoverflow.com/questions/33932901/whats-the-purpose-of-tf-app-flags-in-tensorflow&quot;&gt;stackoverflow&lt;/a&gt;, note that this module is currently packaged as a convenience for writing demo apps, and is not technically part of the public API, so it may change in future. We recommend that you implement your own flag parsing using argparse or whatever library you prefer.&lt;/p&gt;

&lt;h3 id=&quot;load-model&quot;&gt;&lt;strong&gt;Load Model&lt;/strong&gt;&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# freeze model

pickle.dump(predictions, open(&quot;predictions.p&quot;, &quot;wb&quot;))
pickle.dump(history, open(&quot;history.p&quot;, &quot;wb&quot;))
tf.train.write_graph(sess.graph_def, &apos;.&apos;, &apos;har.pbtxt&apos;)
saver.save(sess, save_path=&quot;./har.ckpt&quot;)
sess.close()

from tensorflow.python.tools import freeze_graph

MODEL_NAME = &apos;har&apos;

input_graph_path = MODEL_NAME + &apos;.pbtxt&apos;
checkpoint_path = MODEL_NAME + &apos;.ckpt&apos;
restore_op_name = &quot;save/restore_all&quot;
filename_tensor_name = &quot;save/Const:0&quot;
output_frozen_graph_name = &apos;frozen_&apos; + MODEL_NAME + &apos;.pb&apos;

freeze_graph.freeze_graph(input_graph_path, input_saver=&quot;&quot;,
                          input_binary=False, input_checkpoint=checkpoint_path,
                          output_node_names=&quot;y_&quot;, restore_op_name=&quot;save/restore_all&quot;,
                          filename_tensor_name=&quot;save/Const:0&quot;,
                          output_graph=output_frozen_graph_name, clear_devices=True, initializer_nodes=&quot;&quot;)

#Load Model

with tf.Graph().as_default():
    output_graph_def = tf.GraphDef()

    with open(pb_file_path, &quot;rb&quot;) as f:
        output_graph_def.ParseFromString(f.read())
        _ = tf.import_graph_def(output_graph_def, name=&quot;&quot;)

    with tf.Session() as sess:
        init = tf.global_variables_initializer()
        sess.run(init)
        input_x = tf.get_default_graph().get_tensor_by_name(&quot;input:0&quot;)
        out_softmax = sess.graph.get_tensor_by_name(&quot;prob:0&quot;)
        out_result = sess.run(out_softmax, feed_dict={input_x: reshaped_segments})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Sun, 20 Oct 2019 00:00:00 +0000</pubDate>
        <link>https://guangjing.wang/2019/10/20/tensorflow-notes/</link>
        <guid isPermaLink="true">https://guangjing.wang/2019/10/20/tensorflow-notes/</guid>
        
        <category>TensorFlow</category>
        
        
        <category>System</category>
        
      </item>
    
  </channel>
</rss>
