Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7007 Articles
article-image-ai-now-institute-publishes-a-report-on-the-diversity-crisis-in-ai-and-offers-12-solutions-to-fix-it
Bhagyashree R
22 Apr 2019
7 min read
Save for later

AI Now Institute publishes a report on the diversity crisis in AI and offers 12 solutions to fix it

Bhagyashree R
22 Apr 2019
7 min read
Earlier this month, the AI Now Institute published a report, authored by Sarah Myers West, Meredith Whittaker, and Kate Crawford, highlighting the link between the diversity issue in the current AI industry and the discriminating behavior of AI systems. The report further recommends some solutions to these problems that companies and the researchers behind these systems need to adopt to address these issues. Sarah Myers West is a postdoc researcher at the AI Now Institute and an affiliate researcher at the Berkman-Klein Center for Internet and Society. Meredith Whittaker is the co-founder of the AI Now Institute and leads Google's Open Research Group and the Google Measurement Lab.  Kate Crawford is a Principal Researcher at Microsoft Research and the co-founder and Director of Research at the AI Now Institute. Kate Crawford tweeted about this study. https://twitter.com/katecrawford/status/1118509988392112128 The AI industry lacks diversity, gender neutrality, and bias-free systems In recent years, we have come across several cases of “discriminating systems”. Facial recognition systems miscategorize black people and sometimes fails to work for trans drivers. When trained in online discourse, chatbots easily learn racist and misogynistic language. This type of behavior by machines is actually a reflection of society. “In most cases, such bias mirrors and replicates existing structures of inequality in the society,” says the report. The study also sheds light on gender bias in the current workforce. According to the report, only 18% of authors at some of the biggest AI conferences are women. On the other side of the spectrum are men who cover 80%. The tech giants, Facebook and Google, have a meager 15% and 10% women as their AI research staff. The situation for black workers in the AI industry looks even worse. While Facebook and Microsoft have 4% of their current workforce as black workers, Google stands at just 2.5%. Also, vast majority of AI studies assume gender is binary, and commonly assigns people as ‘male’ or ‘female’ based on physical appearance and stereotypical assumptions, erasing all other forms of gender identity. The report further reveals that, though there have been various “pipeline studies” to check the flow of diverse job candidates, they have failed to show substantial progress in bringing diversity in the AI industry. “The focus on the pipeline has not addressed deeper issues with workplace cultures, power asymmetries, harassment, exclusionary hiring practices, unfair compensation, and tokenization that are causing people to leave or avoid working in the AI sector altogether,” the report reads. What steps can industries take to address bias and discrimination in AI Systems The report lists 12 recommendations that AI researchers and companies should employ to improve workplace diversity and address bias and discrimination in AI systems. Publish compensation levels, including bonuses and equity, across all roles and job categories, broken down by race and gender. End pay and opportunity inequality, and set pay and benefit equity goals that include contract workers, temps, and vendors. Publish harassment and discrimination transparency reports, including the number of claims over time, the types of claims submitted, and actions taken. Change hiring practices to maximize diversity: include targeted recruitment beyond elite universities, ensure more equitable focus on under-represented groups, and create more pathways for contractors, temps, and vendors to become full-time employees. Commit to transparency around hiring practices, especially regarding how candidates are leveled, compensated, and promoted. Increase the number of people of color, women and other under-represented groups at senior leadership levels of AI companies across all departments. Ensure executive incentive structures are tied to increases in hiring and retention of underrepresented groups. For academic workplaces, ensure greater diversity in all spaces where AI research is conducted, including AI-related departments and conference committees. Remedying bias in AI systems is almost impossible when these systems are opaque. Transparency is essential, and begins with tracking and publicizing where AI systems are used, and for what purpose. Rigorous testing should be required across the lifecycle of AI systems in sensitive domains. Pre-release trials, independent auditing, and ongoing monitoring are necessary to test for bias, discrimination, and other harms. The field of research on bias and fairness needs to go beyond technical debiasing to include a wider social analysis of how AI is used in context. This necessitates including a wider range of disciplinary expertise. The methods for addressing bias and discrimination in AI need to expand to include assessments of whether certain systems should be designed at all, based on a thorough risk assessment. AI-related departments and conference committees. Credits: AI Now Institute Bringing diversity in the AI workforce In order to address the diversity issue in the AI industry, companies need to make changes in the current hiring practices. They should have a more equitable focus on under-represented groups. People of color, women, and other under-represented groups should get fair chance to get into senior leadership level of AI companies across all departments. Further opportunities should be created for contractors, temps, and vendors to become full-time employees. To bridge the gender pay gap in the AI industry, it is important that companies maintain transparency regarding the compensation levels, including bonuses and equity, regardless of gender or race. In the past few years, several cases of sexual misconducts involving some of the biggest companies like Google, Microsoft, have come into light because of movements like #MeToo, Google Walkout, and more. These movements gave the victims and other supporting employees  the courage to speak against employees at higher positions who were taking undue advantage of their power. There are cases were the sexual harassment complaints were not taken seriously by the HRs and victims were told to just “get over it”. This is why, companies should  publish harassment and discrimination transparency reports that include information like the number and types of claims made and the actions taken by the company. Academic workplaces should ensure diversity in all AI-related departments and conference committees. In the past, some of the biggest AI conferences like Neural Information Processing Systems conference has failed to provide a welcoming and safer environment for women. In a survey conducted last year, many respondents shared that they have experienced sexual harassment. Women reported persistent advances from men at the conference. The organizers of such conferences should ensure an inclusive and welcoming environment for everyone. Addressing bias and discrimination in AI systems To address bias and discrimination in AI systems, the report recommends to do rigorous testing across the lifecycle of these systems. These systems should have pre-release trials, independent auditing, and monitoring to check bias, discrimination, and other harms. Looking at the social implications of AI systems, just addressing the algorithmic bias is not enough. “The field of research on bias and fairness needs to go beyond technical debiasing to include a wider social analysis of how AI is used in context. This necessitates including a wider range of disciplinary expertise,” says the report. While assessing a AI system, researchers and developers should also check whether designing a certain system is required at all, considering the risks it poses. The study calls for re-evaluating the current AI systems used for classifying, detecting, and predicting the race and gender. The idea of identifying a race or gender just by appearance is flawed and can be easily abused. Especially, systems that use physical appearance to find interior states, for instance, those that claim to detect sexuality from headshots. These systems are urgently in need to be checked. To know more in detail, read the full report: Discriminating Systems. Microsoft’s #MeToo reckoning: female employees speak out against workplace harassment and discrimination Desmond U. Patton, Director of SAFElab shares why AI systems should be a product of interdisciplinary research and diverse teams Google’s Chief Diversity Officer, Danielle Brown resigns to join HR tech firm Gusto
Read more
  • 0
  • 0
  • 19011

article-image-how-to-build-topic-models-in-r-tutorial
Natasha Mathur
22 Apr 2019
8 min read
Save for later

How to build topic models in R [Tutorial]

Natasha Mathur
22 Apr 2019
8 min read
Topic models are a powerful method to group documents by their main topics. Topic models allow probabilistic modeling of term frequency occurrence in documents. The fitted model can be used to estimate the similarity between documents, as well as between a set of specified keywords using an additional layer of latent variables, which are referred to as topics (Grun and Hornik, 2011). In essence, a document is assigned to a topic based on the distribution of the words in that document, and the other documents in that topic will have roughly the same frequency of words. In this tutorial, we will look at a useful framework for text mining, called topic models. We will apply the framework to the State of the Union addresses. In building topic models, the number of topics must be determined before running the algorithm (k-dimensions). If no prior reason for the number of topics exists, then you can build several and apply judgment and knowledge to the final selection. There are different methods that come under Topic Modeling. We'll look at LDA with Gibbs sampling. This method is quite complicated mathematically, but my intent is to provide an introduction so that you are at least able to describe how the algorithm learns to assign a document to a topic in layperson terms. If you are interested in mastering the math associated with the method, block out a couple of hours on your calendar and have a go at it. Excellent background material can be found here.  This tutorial is an excerpt taken from the book 'Mastering Machine Learning with R - Third Edition' written by Cory Lesmeister. The book explores expert techniques for solving data analytics and covers machine learning challenges that can help you gain insights from complex projects and power up your applications. Talking about LDA  or Latent Dirichlet Allocation in topic modeling, it is a generative process, and works in the following manner to iterate to a steady state: For each document (j), there are 1 to j documents. We will randomly assign a multinomial distribution (Dirichlet distribution) to the topics (k) with 1 to k topics, for example, document A is 25 percent topic one, 25 percent topic two, and 50 percent topic three. Probabilistically, for each word (i), there are 1 to i words to a topic (k); for example, the word mean has a probability of 0.25 for the topic statistics. For each word (i) in document (j) and topic (k), calculate the proportion of words in that document assigned to that topic; note it as the probability of topic (k) with document (j), p(k|j), and the proportion of word (i) in topic (k) from all the documents containing the word. Note it as the probability of word (i) with topic (k), p(i|k). Resample, that is, assign w a new t based on the probability that t contains w, which is based on p(k|j) times p(i|k). Rinse and repeat; over numerous iterations, the algorithm finally converges and a document is assigned a topic based on the proportion of words assigned to a topic in that document. The LDA assumes that the order of words and documents does not matter. There has been work done to relax these assumptions in order to build models of language generation and sequence models over time (known as dynamic topic modeling or DTM). Applying Topic models in State of the Union addresses We will leave behind the 19th century and look at these recent times of trial and tribulation (1965 through 2016). On looking at this data, I found something interesting and troubling. Let's take a look at the 1970s: > sotu_meta[185:191, 1:4] # A tibble: 7 x 4 president year years_active party <chr> <int> <chr> <chr> 1 Richard M. Nixon 1970 1969-1973 Republican 2 Richard M. Nixon 1971 1969-1973 Republican 3 Richard M. Nixon 1972 1969-1973 Republican 4 Richard M. Nixon 1972 1969-1973 Republican 5 Richard M. Nixon 1974 1973-1974 Republican 6 Richard M. Nixon 1974 1973-1974 Republican 7 Gerald R. Ford 1975 1974-1977 Republican We see there are two 1972 and two 1974 addresses, but none for 1973. What? I went to the Nixon Foundation website, spent about 10 minutes trying to deconflict this, and finally threw my hands in the air and decided on implementing a quick fix. Be advised that there are a number of these conflicts to put in order: > sotu_meta[188, 2] <- "1972_2" > sotu_meta[190, 2] <- "1974_2" > sotu_meta[157, 2] <- "1945_2" > sotu_meta[166, 2] <- "1953_2" > sotu_meta[170, 2] <- "1956_2" > sotu_meta[176, 2] <- "1961_2" > sotu_meta[195, 2] <- "1978_2" > sotu_meta[197, 2] <- "1979_2" > sotu_meta[199, 2] <- "1980_2" > sotu_meta[201, 2] <- "1981_2" An email to the author of this package is in order. I won't bother with that, but feel free to solve the issue yourself. With this tragedy behind us, we'll go through tokenizing and removing stop words again for our relevant time frame: > sotu_meta_recent <- sotu_meta %>% dplyr::filter(year > 1964) > sotu_meta_recent %>% tidytext::unnest_tokens(word, text) -> sotu_unnest_recent > sotu_recent <- sotu_unnest_recent %>% dplyr::anti_join(stop_words, by = "word") As discussed previously, we need to put the data into a DTM before building a model. This is done by creating a word count grouped by year, then passing that to the cast_dtm() function: > sotu_recent %>% dplyr::group_by(year) %>% dplyr::count(word) -> lda_words > sotu_dtm <- tidytext::cast_dtm(lda_words, year, word, n) Let's get our model built. I'm going to create six different topics using the Gibbs method, and I specified verbose. It should run 2,000 iterations: > sotu_lda <- topicmodels::LDA( sotu_dtm, k = 6, method = "Gibbs", control = list(seed = 1965, verbose = 1) ) > sotu_lda A LDA_Gibbs topic model with 6 topics. The algorithm gives each topic a number. We can see what year is mapped to what topic. I abbreviate the output since 2002: > topicmodels::topics(sotu_lda) 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2 2 2 2 2 2 2 4 4 4 4 4 4 4 4 We see a clear transition between Bush and Obama from topic 2 to topic 4. Here is a table of the count of topics: > table(topicmodels::topics(sotu_lda)) 1 2 3 4 5 6 8 7 5 18 14 5 Topic 4 is the most prevalent, which is associated with Clinton's term also. This output gives us the top five words associated with each topic: > topicmodels::terms(sotu_lda, 5) Topic 1 Topic 2 Topic 3 [1,] "future" "america" "administration" [2,] "tax" "security" "congress" [3,] "spending" "country" "economic" [4,] "government" "world" "legislation" [5,] "economic" "iraq" "energy" Topic 4 Topic 5 Topic 6 [1,] "people" "world" "federal" [2,] "american" "people" "programs" [3,] "jobs" "american" "government" [4,] "america" "congress" "program" [5,] "children" "peace" "act" This all makes good sense, and topic 2 is spot on for the time. If you drill down further to, say, 10, 15, or 20 words, it is even more revealing, but I won't bore you further. What about an application in the tidy ecosystem and a visualization? Certainly! We'll turn the model object into a data frame first and in the process capture the per-topic-per-word probabilities called beta: > lda_topics <- tidytext::tidy(sotu_lda, matrix = "beta") > ap_top_terms <- lda_topics %>% dplyr::group_by(topic) %>% dplyr::top_n(10, beta) %>% dplyr::ungroup() %>% dplyr::arrange(topic, -beta) We can explore that data further or just plot it as follows: > ap_top_terms %>% dplyr::mutate(term = reorder(term, beta)) %>% ggplot2::ggplot(ggplot2::aes(term, beta, fill = factor(topic))) + ggplot2::geom_col(show.legend = FALSE) + ggplot2::facet_wrap(~ topic, scales = "free") + ggplot2::coord_flip() + ggthemes::theme_economist_white() The output of the preceding code is as follows: This is the top 10 words per topic based on the beta probability. Another thing we can do is look at the probability an address is related to a topic. This is referred to as gamma in the model and we can pull those in just like the beta: > ap_documents <- tidytext::tidy(sotu_lda, matrix = "gamma") We now have the probabilities of an address per topic. Let's look at the 1981 Ronald Reagan values: > dplyr::filter(ap_documents, document == "1981") # A tibble: 6 x 3 document topic gamma <chr> <int> <dbl> 1 1981 1 0.286 2 1981 2 0.0163 3 1981 3 0.0923 4 1981 4 0.118 5 1981 5 0.0777 6 1981 6 0.411 Topic 1 is a close second in the topic race. If you think about it, this means that more than six topics would help to create better separation in the probabilities. However, I like just six topics for this tutorial for the purpose of demonstration. In this tutorial, we looked at topic models in R. We applied the framework to the State of the Union addresses.  If you want to stay updated with expert techniques for solving data analytics and explore other machine learning challenges in R, be sure to check out the book 'Mastering Machine Learning with R - Third Edition'. How to make machine learning based recommendations using Julia [Tutorial] The rise of machine learning in the investment industry GitHub Octoverse: top machine learning packages, languages, and projects of 2018
Read more
  • 0
  • 0
  • 12195

article-image-brett-lantz-shows-how-data-scientists-learn-building-algorithms-in-third-edition-machine-learning-r
Packt Editorial Staff
22 Apr 2019
3 min read
Save for later

The hands-on guide to Machine Learning with R by Brett Lantz

Packt Editorial Staff
22 Apr 2019
3 min read
If science fiction stories are to be believed, the invention of Artificial Intelligence inevitably leads to apocalyptic wars between machines and their makers. Thankfully, at the time of this writing, machines still require user input. Though your impressions of Machine Learning may be colored by these mass-media depictions, today's algorithms are too application-specific to pose any danger of becoming self-aware. The goal of today's Machine Learning is not to create an artificial brain, but rather to assist us with making sense of the world's massive data stores. Conceptually, the learning process involves the abstraction of data into a structured representation, and the generalization of the structure into action that can be evaluated for utility. In practical terms, a machine learner uses data containing examples and features of the concept to be learned, then summarizes this data in the form of a model, which is used for predictive or descriptive purposes. The field of machine learning provides a set of algorithms that transform data into actionable knowledge. Among the many possible methods, machine learning algorithms are chosen on the basis of the input data and the learning task. This fact makes machine learning well-suited to the present-day era of big data. Machine Learning with R, Third Edition introduces you to the fundamental concepts that define and differentiate the most commonly used machine learning approaches and how easy it is to use R to start applying machine learning to real-world problems. Many of the algorithms needed for machine learning are not included as part of the base R installation. Instead, the algorithms are available via a large community of experts who have shared their work freely. These powerful tools are available to download at no cost, but must be installed on top of base R manually. This book covers a small portion of all of R's machine learning packages and will get you up to speed with the learning landscape of machine learning with R. Machine Learning with R, Third Edition updates the classic R data science book with newer and better libraries, advice on ethical and bias issues in machine learning, and an introduction to deep learning. Whether you are an experienced R user or new to the language, Brett Lantz teaches you everything you need to uncover key insights, make new predictions, and visualize your findings. Introduction to Machine Learning with R Machine Learning with R How to make machine learning based recommendations using Julia [Tutorial]
Read more
  • 0
  • 0
  • 7754

article-image-how-to-translate-openqasm-programs-in-ibx-qx-into-quantum-scores-tutorial
Natasha Mathur
21 Apr 2019
8 min read
Save for later

How to translate OpenQASM programs in IBX QX into quantum scores [Tutorial]

Natasha Mathur
21 Apr 2019
8 min read
Open Quantum Assembly Language (OpenQASM, pronounced open kazm) is a custom programming language designed specifically to minimally describe quantum circuits. In this tutorial, we will learn how to translate OpenQASM programs into quantum scores with IBM QX. We will also look at representing quantum scores in OpenQASM 2.0 programs. You will need a modern web browser and the ability to sign into IBM QX This tutorial is an excerpt taken from the book 'Mastering Quantum Computing with IBM QX' written by  Dr. Christine Corbett Moran. The book explores quantum computing by implementing quantum programs on IBM QX, helping you be at the forefront of the next revolution in computation. The Quantum Composer is a tool to specify quantum programs graphically, and many SDKs and APIs exist to write compute code to represent a quantum program in a modern language (Python being a common choice). Like the Quantum Composer, OpenQASM a higher-level language for specifying quantum programs than computer code, but unlike the Quantum Composer, it is neither graphical nor user interface specific, so it can be much easier to specify longer programs that can be directly copied into the many quantum simulators or into IBM QX for use. The Quantum Composer can take as input, programs in OpenQASM, and translate them into the graphical view. Likewise, for every program specified in the Quantum Composer it is easy to access the equivalent in OpenQASM within the IBM QX user interface. OpenQASM is similar in syntax to C: Comments are one per line and begin with // White space isn't important Case is important Every line in the program must end in a semicolon ; Additionally, the following points apply: Every program must begin with  OPENQASM 2.0; (IBM QX at the time of writing uses version 2.0, but this can be updated to whichever version of OpenQASM you are using). When working with IBM QX, the include "qelib1.inc"; header must be given. Any other file can be included with the same syntax; what OpenQASM does is simply copies the content of the file at the location of include. The path to the file is a relative path from the current program. Reading and writing OpenQASM 2.0 programs for the IBM QX will involve the following operations: Include header include "qelib1.inc"; Declaring a quantum register (qregname is any name you choose for the quantum register) qreg qregname[k]; Referencing a quantum register qregname[i]; Declaring a classical register (cregname is any name you choose for the quantum register) creg cregname[k]; Referencing a classical register cregname[i]; One-qubit gate list, available with inclusion of qelib1.inc on IBM QX h, t, tdg, s, sdg, x, y, z, id One-qubit gate action syntax gate q[i]; Two-qubit CNOT gate list, available with inclusion of qelib1.inc on IBM QX cx Two-qubit CNOT gate action (control and target both qubits in a previously declared quantum register) cnot control, target; Measurement operations available  measure, bloch Measurement operation action syntax measure q[i] -> c[j]; bloch q[i] -> c[j]; Barrier operation (args are a comma-separated list of qubits) barrier args; Primitive gates (OpenQASM standard but not used on IBM QX) CX, U We will now learn reading OpenQASM programs and translating them into quantum scores as well as translating quantum scores to OpenQASM programs. Note that i and j are integer counters, starting at 0, which specifies which qubit/bit in the quantum or classical register the program would like to reference; k is an integer counter greater than 0 which specifies the size of a classical or quantum register at declaration. Translating OpenQASM programs into quantum scores In this tutorial, we will translate OpenQASM programs into quantum scores by hand to practice, reading OpenQASM code. OpenQASM to negate one qubit Consider the following program: OPENQASM 2.0; include "qelib1.inc"; qreg q[1]; x q[0]; The following lines are the standard headers for working with IBM QX: OPENQASM 2.0; include "qelib1.inc"; Then the following line declares a quantum register of size one named q: qreg q[1]; Quantum registers are automatically initialized to contain |"0">. Finally, the next line operates the X gate on the first (and only) qubit in the  q quantum register: x q[0]; Putting this all together, we can create the following equivalent quantum score: OpenQASM to apply gates to two qubits, and measure the first qubit Next, consider the OpenQASM program: OPENQASM 2.0; include "qelib1.inc"; qreg q[2]; creg c[1]; x q[0]; y q[0]; z q[0]; s q[1]; measure q[0] -> c[0]; The first two preceding lines are the standard header to declare a program and OpenQASM program and the standard import header to interface with the IBM QX. The next two lines declare a quantum register of two qubits initialized to |"00"> and a classical register of one bit initialized to 0: qreg q[2]; creg c[1]; The next three lines apply gates, in order, to the first qubit in the q quantum register: x q[0]; y q[0]; z q[0]; The next line applies a gate to the second qubit in the q quantum register: s q[1]; And the final line measures the first qubit in the q quantum register and places the result in the first (and only) bit in the c classical register: measure q[0] -> c[0]; Putting this all together, we can create the following equivalent quantum score: Representing quantum scores in OpenQASM 2.0 programs Here is an example of writing an OpenQASM 2.0 program from a quantum score. I have broken it down into columns from top to bottom of the score for clarity and annotated these in the diagram by indicating column numbers in orange. Here's the circuit illustrating the reversibility of quantum computations: Let's dissect the OpenQASM that generates this circuit. The first lines are, as usual, the headers, indicating the code is OpenQASM and that we will be using the standard IBM QX header: OPENQASM 2.0; include "qelib1.inc"; The next lines declare a quantum register named q  of 5 qubits  initialized to |"00000"> and a classical register name c of 5 bits initialized to 00000: // declare the quantum and classical registers we will use qreg q[5]; creg c[5]; The next lines will go column by column in the circuit diagram, creating the code for each column in order. We will start with the first column: The first column we can see only contains a CNOT gate, with its control qubit being the third qubit in the q quantum register, q[2] and the target qubit being the second qubit in the q quantum register, q[1]. Looking up the OpenQASM syntax for the CNOT gate in the table in the previous section, we see that it is cnot control, target; which means that the first column will be coded as: //column 1 cx q[2],q[1]; Next, we will move to the second column, which has a number of gates specified. The code for the second column is: //column2 x q[1]; h q[2]; s q[3]; y q[4]; Each successive column should now be straightforward to encode from looking at the quantum score in OpenQASM. The full program is as follows: OPENQASM 2.0; include "qelib1.inc"; // declare the quantum and classical registers we will use qreg q[5]; creg c[5]; //column 1 cx q[2],q[1]; //column2 x q[1]; h q[2]; s q[3]; y q[4]; //column 3 t q[2]; z q[3]; //column 4 tdg q[2]; z q[3]; //column 5 x q[1]; h q[2]; sdg q[3]; y q[4]; // column 6 cx q[2],q[1]; // column 7 measure q[0] -> c[0]; // column 8 measure q[1] -> c[1]; // column 9 measure q[2] -> c[2]; // column 10 measure q[3] -> c[3]; // column 11 measure q[4] -> c[4]; The previous code exactly reproduced the quantum score as depicted, but we could make several quantum scores, which are equivalent (and thus several variations on the OpenQASM program that are equivalent), as we saw in previous sections. Here are a couple of things to keep in mind: Each column could be in any order, for example, column 3 could be: t q[2]; z q[3]; Or it could be: z q[3]; tdg q[2]; In addition, any gate operating on a qubit in any column where there is no gate in the previous column on the qubit can be moved to the previous column, without affecting the computation. In this article, we learned how to translate OpenQASM programs in IBX QX into quantum scores. We also looked at Representing quantum scores in OpenQASM 2.0 programs. If you want to learn other concepts and principles of Quantum Computing with IBM QX, be sure to check out the book 'Mastering Quantum Computing with IBM QX'. Quantum computing, edge analytics, and meta-learning: key trends in data science and big data in 2019 Did quantum computing just take a quantum leap? A two-qubit chip by UK researchers makes quantum entanglement possible Quantum Computing is poised to take a quantum leap with industries and governments on its side
Read more
  • 0
  • 0
  • 34740

article-image-using-qiskit-with-ibm-qx-to-generate-quantum-circuits-tutorial
Natasha Mathur
20 Apr 2019
5 min read
Save for later

Using Qiskit with IBM QX to generate quantum circuits [Tutorial]

Natasha Mathur
20 Apr 2019
5 min read
This tutorial expands on the idea of quantum gates to introduce quantum circuits, the quantum analog of classical circuits. It goes over how classical gates can be reproduced by quantum circuits and proceeds to introduce a visual representation of quantum circuits that can be used to easily define a quantum circuit without reference to mathematics or use of a programming language. In this tutorial, we will look at how to use Qiskkit to generate quantum circuits. The Jupyter Notebook for this tutorial is available under chapter 05 at Github. This tutorial is an excerpt taken from the book Mastering Quantum Computing with IBM QX written by Dr. Christine Corbett Moran. The book explores principles of quantum computing and the areas in which they can be applied. You'll also learn about the IBM Ecosystem and Qiskit. Note: Every classic bit, either 0 or 1, can be written as either a "0" or a "1" qubit, which to show that it is a qubit, is written as a name surrounded by | and >. So, for example, the qubit named "0" is written as |"0"> and the qubit named "1" is written as |"1">. Throughout this post, the qubits will always be written as names surrounded by quotation marks and | and > to indicate that they are, indeed, qubits. Qiskit is the Quantum Information Science Kit. It is an SDK for working with the IBM QX quantum processors. It also has a variety of tools to simulate a quantum computer in Python. In this tutorial, we are going to learn to use it to generate quantum circuits. Single-qubit circuits in Qiskit First, let's import the tools to create classical and quantum registers as well as quantum circuits from qiskit: from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister Next let's make the X |"0"> circuit using qiskit: qr = QuantumRegister(1) circuit = QuantumCircuit(qr) circuit.x(qr[0]) Note that the argument to QuantumRegister is 1; this indicates that the quantum register is to contain one qubit. The XH|"0"> circuit using qiskit becomes the following: qr = QuantumRegister(1) circuit = QuantumCircuit(qr) circuit.h(qr[0]) circuit.x(qr[0]) Qiskit's QuantumCircuit class and universal gate methods We can see that the QuantumCircuit class allows us to execute a variety of gates on particular qubits in the quantum register used to initial it. The full gate set is available in the QuantumCircuit documentation, but I will give the equivalent of the gates we have learned so far: Gate Qiskit QuantumCircuit class method name I iden X x Y y Z z H h S s S† sdg T t T† tdg CNOT cx Multiqubit gates in Qiskit Now suppose we want to use qiskit to construct a circuit for CNOT using |"+"> as the control qubit and |"0"> as the target qubit. We will need to create a quantum register to hold two qubits with qr = QuantumRegister(2). We will also need to give each qubit in the register as an argument to the cx method of the QuantumCircuit class. The first qubit argument to cx is the control qubit; the second is the target qubit. The code is as follows: qr = QuantumRegister(2) circuit = QuantumCircuit(qr) circuit.h(qr[0]) circuit.cx(qr[0],qr[1]) Classical registers in Qiskit circuit We can add a classical register to our quantum circuit. We will need a classical register to hold the output of a measurement. Here is an example of adding a classical register to the circuit for CNOT using |"+"> as the control qubit and |"0"> as the target qubit: qr = QuantumRegister(2) cr = ClassicalRegister(2) circuit = QuantumCircuit(qr, cr) circuit.h(qr[0]) circuit.cx(qr[0],qr[1]) Here we can see that just like creating an instance of the QuantumRegister class requires us to specify the length of the quantum register in qubits, creating an instance of the ClassicalRegister class requires us to specify the size of the classical register in bits. Here we can see that initializing a member of the QuantumCircuit class with a classical register means that we need to give the ClassicalRegister instance as a second argument to the QuantumCircuit constructor. Measurement in a Qiskit circuit Now that we have a circuit with a two-qubit quantum register and a two-qubit classical register, we can perform a measurement of all the qubits in the circuit with the measure method of the QuantumCircuit class. This method takes as input the quantum register to measure as well as the classical register in which to place the result. Here is an example: qr = QuantumRegister(2) cr = ClassicalRegister(2) circuit = QuantumCircuit(qr, cr) circuit.h(qr[0]) circuit.cx(qr[0],qr[1]) circuit.measure(qr, cr) Note that we can also decide to measure just an individual qubit, by specifying which qubit to measure and which bit to put the output result in the following: qr = QuantumRegister(2) cr = ClassicalRegister(2) circuit = QuantumCircuit(qr, cr) circuit.h(qr[0]) circuit.cx(qr[0],qr[1]) circuit.measure(qr[0], cr[0]) That's it. We learned how to use Qiskit to write python code to represent different quantum circuits namely, single-qubit circuits, Qiskit's QuantumCircuit class, and universal gate methods, Multiqubit gates in Qiskit, Classical registers in Qiskit circuit, and Measurement in a Qiskit circuit. If you want to learn other core concepts and principles of Quantum computing with IBM QX, be sure to check out Mastering Quantum Computing with IBM QX. IBM Q System One, IBM’s standalone quantum computer unveiled at CES 2019 IBM launches Industry's first 'Cybersecurity Operations Center on Wheels' for on-demand cybersecurity support Say hello to IBM RXN, a free AI Tool in IBM Cloud for predicting chemical reactions
Read more
  • 0
  • 0
  • 26110

article-image-training-deep-convolutional-gans-to-generate-anime-characters-tutorial
Natasha Mathur
19 Apr 2019
19 min read
Save for later

Training Deep Convolutional GANs to generate Anime Characters [Tutorial]

Natasha Mathur
19 Apr 2019
19 min read
Convolution layers are really good at processing images. They are capable of learning important features, such as edges, shapes, and complex objects, effectively, as shown in neural networks, such as Inception, AlexNet, Visual Geometry Group (VGG), and ResNet. In this tutorial, we will use a DCGAN architecture to generate anime characters. We will learn to prepare the dataset for training, Keras implementation of a DCGAN for the generation of anime characters, and training the DCGAN on the anime character dataset. The development of Deep Convolutional Generative Adversarial Networks (DCGANs) was an important step towards using CNNs for image generation. A DCGAN uses convolutional layers instead of dense layers and were proposed by researchers Alec Radford, Luke Metz, Soumith Chintala, and others, in their paper, Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks. Since then, DCGANs have been widely used for various image generation tasks. This tutorial is an excerpt taken from the book 'Generative Adversarial Networks Projects' written by Kailash Ahirwar. The book explores unsupervised techniques for training neural networks and includes seven end-to-end projects in the GAN domain. Downloading and preparing the anime characters dataset To train a DCGAN network, we need a dataset of anime characters containing cropped faces of the characters. In this tutorial, we will be scraping images for educational and demonstration purposes only. We have scraped images from pixiv.net using a crawler tool called gallery-dl. This is a command-line tool that can be used to download image collections from websites, such as pixiv.net, exhentai.org, danbooru.donmai.us, and more. It is available at the following link: https://github.com/mikf/gallery-dl. Downloading the dataset In this section, we will cover the different steps required to install the dependencies and download the dataset. Before executing the following commands, activate the virtual environment created for this project: Execute the following command to install gallery-dl: pip install --upgrade gallery-dl Alternatively, you can install the latest development version of gallery-dl using the following command: pip install --upgrade https://github.com/mikf/gallery-dl/archive/master.zip If the preceding commands don't work, follow the instructions given in the official repository: # Official gallery-dl Github repo https://github.com/mikf/gallery-dl Finally, execute the following command to download the images from danbooru.donmai.us using gallery-dl.: gallery-dl https://danbooru.donmai.us/posts?tags=face Download images at your own risk. The information given is for educational purposes only and we don't support illegal scraping. We don't have copyright of the images, as the images are hosted by their respective owners. For commercial purposes, please contact the respective owner of the website or the content that you are using. Exploring the dataset Before we crop or resize the images, take a look at the downloaded images: As you see, some images contain other body parts as well, which we don't want in our training images. In the next section, we will crop out only the face part of these images. Also, we will resize all images to a size required for the training. Cropping and resizing images in the dataset In this section, we will crop out faces from images. We will be using python-animeface to crop the faces from the images. This is an open source GitHub repository that automatically crops faces from images from the command line. It is publicly available at the following link: https://github.com/nya3jp/python-animeface. Execute the following steps to crop and resize the images: First of all, download python-animeface: pip install animeface Next, import the module required for the task: import glob import os import animeface from PIL import Image Next, define the parameters: total_num_faces = 0 Next, iterate over all images to crop and resize them one by one: for index, filename in enumerate(glob.glob('/path/to/directory/containing/images/*.*')): Inside the loop, open the current image and detect a face inside it: try: # Open image im = Image.open(filename) # Detect faces faces = animeface.detect(im) except Exception as e: print("Exception:{}".format(e)) continue Next, get coordinates of the face detected in the images: fp = faces[0].face.pos # Get coordinates of the face detected in the image coordinates = (fp.x, fp.y, fp.x+fp.width, fp.y+fp.height) Now, crop the face out of the image: # Crop image cropped_image = im.crop(coordinates) Next, resize the cropped face image to have a dimension of (64, 64): # Resize image cropped_image = cropped_image.resize((64, 64), Image.ANTIALIAS) Finally, save the cropped and resized image to the desired directory: cropped_image.save("/path/to/directory/to/store/cropped/images/filename.png")) The complete code wrapped inside a Python function appears as follows: import glob import os import animeface from PIL import Image total_num_faces = 0 for index, filename in enumerate(glob.glob('/path/to/directory/containing/images/*.*')): # Open image and detect faces try: im = Image.open(filename) faces = animeface.detect(im) except Exception as e: print("Exception:{}".format(e)) continue # If no faces found in the current image if len(faces) == 0: print("No faces found in the image") continue fp = faces[0].face.pos # Get coordinates of the face detected in the image coordinates = (fp.x, fp.y, fp.x+fp.width, fp.y+fp.height) # Crop image cropped_image = im.crop(coordinates) # Resize image cropped_image = cropped_image.resize((64, 64), Image.ANTIALIAS) # Show cropped and resized image # cropped_image.show() # Save it in the output directory cropped_image.save("/path/to/directory/to/store/cropped/images/filename.png")) print("Cropped image saved successfully") total_num_faces += 1 print("Number of faces detected till now:{}".format(total_num_faces)) print("Total number of faces:{}".format(total_num_faces)) The preceding script will load all of the images from the folder containing downloaded images, detect faces using the python-animeface library, and crop out the face part from the initial image. Then, the cropped images will be resized to a size of 64 x 64. If you want to change the dimensions of the images, change the architecture of the generator and the discriminator accordingly. We are now ready to work on our network. Implementing a DCGAN using Keras In this section, we will write an implementation of a DCGAN in the Keras framework. Keras is a meta-framework that uses TensorFlow or Teano as a backend. It provides high-level APIs for working with neural networks.  Let's start by writing the implementation of the generator network. Generator The generator network consists of some 2D convolutional layers, upsampling layers, a reshape layer, and a batch normalization layer. In Keras, every operation can be specified as a layer. Even activation functions are layers in Keras and can be added to a model just like a normal dense layer. Perform the following steps to create a generator network: Let's start by creating a Sequential Keras model: gen_model = Sequential() Next, add a dense layer that has 2,048 nodes, followed by an activation layer, tanh: gen_model.add(Dense(units=2048)) gen_model.add(Activation('tanh')) Next, add the second layer, which is also a dense layer that has 16,384 neurons. This is followed by a batch normalization layer with default hyperparameters and tanh as the activation function: gen_model.add(Dense(256*8*8)) gen_model.add(BatchNormalization()) gen_model.add(Activation('tanh')) The output of the second dense layer is a tensor of a size of (16384,). Here, (256, 8, 8) is the number of neurons in the dense layer. Next, add a reshape layer to the network to reshape the tensor from the last layer to a tensor of a shape of (batch_size, 8, 8, 256): # Reshape layer gen_model.add(Reshape((8, 8, 256), input_shape=(256*8*8,))) Next, add a 2D upsampling layer to alter the shape from (8, 8, 256) to (16, 16, 256). The upsampling size is (2, 2), which increases the size of the tensor to double its original size. Here, we have 256 tensors of a dimension of 16 x 16: gen_model.add(UpSampling2D(size=(2, 2))) Next, add a 2D convolutional layer. This applies 2D convolutions on the tensor using a specified number of filters. Here, we are using 64 filters and a kernel of a shape of (5, 5): gen_model.add(Conv2D(128, (5, 5), padding='same')) gen_model.add(Activation('tanh')) Next, add a 2D upsampling layer to change the shape of the tensor from (batch_size, 16, 16, 64) to (batch_size, 32, 32, 64): gen_model.add(UpSampling2D(size=(2, 2))) A 2D upsampling layer repeats the rows and columns of the tensor by a size of [0] and a size of [1], respectively. Next, add a second 2D convolutional layer with 64 filters and a kernel size of (5, 5) followed by tanh as the activation function: gen_model.add(Conv2D(64, (5, 5), padding='same')) gen_model.add(Activation('tanh')) Next, add a 2D upsampling layer to change the shape from (batch_size, 32, 32, 64) to (batch_size, 64, 64, 64): gen_model.add(UpSampling2D(size=(2, 2))) Finally, add the third 2D convolutional layer with three filters and a kernel size of (5, 5) followed by tanh as the activation function: gen_model.add(Conv2D(3, (5, 5), padding='same')) gen_model.add(Activation('tanh')) The generator network will output a tensor of a shape of (batch_size, 64, 64, 3). One image tensor from this batch of tensors is similar to an image of a dimension of 64 x 64 with three channels: Red, Green, and Blue (RGB). The complete code for the generator network wrapped in a Python method looks as follows: def get_generator(): gen_model = Sequential() gen_model.add(Dense(input_dim=100, output_dim=2048)) gen_model.add(LeakyReLU(alpha=0.2)) gen_model.add(Dense(256 * 8 * 8)) gen_model.add(BatchNormalization()) gen_model.add(LeakyReLU(alpha=0.2)) gen_model.add(Reshape((8, 8, 256), input_shape=(256 * 8 * 8,))) gen_model.add(UpSampling2D(size=(2, 2))) gen_model.add(Conv2D(128, (5, 5), padding='same')) gen_model.add(LeakyReLU(alpha=0.2)) gen_model.add(UpSampling2D(size=(2, 2))) gen_model.add(Conv2D(64, (5, 5), padding='same')) gen_model.add(LeakyReLU(alpha=0.2)) gen_model.add(UpSampling2D(size=(2, 2))) gen_model.add(Conv2D(3, (5, 5), padding='same')) gen_model.add(LeakyReLU(alpha=0.2)) return gen_model Now we have created the generator network, let's work on creating the discriminator network. Discriminator The discriminator network has three 2D convolutional layers, each followed by an activation function followed by two max-pooling layers. The tail of the network contains two fully-connected (dense) layers that work as a classification layer. Perform the following steps to create a discriminator network: Let's start by creating a Sequential Keras model: dis_model = Sequential() Add a 2D convolutional layer that takes an input image of a shape of (64, 64, 3). The hyperparameters for this layer are the following. Also, add LeakyReLU with an alpha value of 0.2 as the activation function: Filters: 128 Kernel Size: (5, 5) Padding: Same: dis_model.add(Conv2D(filters=128, kernel_size=5, padding='same', input_shape=(64, 64, 3))) dis_model.add(LeakyReLU(alpha=0.2)) Next, add a 2D max pooling layer with a pool size of (2, 2). Max pooling is used to downsample an image representation and it is applied by using a max-filter over non-overlapping sub-regions of the representation: dis_model.add(MaxPooling2D(pool_size=(2, 2))) The shape of the output tensor from the first layer will be (batch_size, 32, 32, 128). Next, add another 2D convolutional layer with the following configurations: Filters: 256 Kernel size: (3, 3) Activation function: LeakyReLU with alpha 0.2 Pool size in 2D max pooling: (2, 2): dis_model.add(Conv2D(filters=256, kernel_size=3)) dis_model.add(LeakyReLU(alpha=0.2)) dis_model.add(MaxPooling2D(pool_size=(2, 2))) The shape of the output tensor from this layer will be (batch_size, 30, 30, 256). Next, add the third 2D convolutional layer with the following configurations: Filters: 512 Kernel size: (3, 3) Activation function: LeakyReLU with alpha 0.2 Pool size in 2D Max Pooling: (2, 2): dis_model.add(Conv2D(512, (3, 3))) dis_model.add(LeakyReLU(alpha=0.2)) dis_model.add(MaxPooling2D(pool_size=(2, 2))) The shape of the output tensor from this layer will be (batch_size, 13, 13, 512). Next, add a flatten layer. This flattens the input without affecting the batch size. It produces a two-dimensional tensor: dis_model.add(Flatten()) The output shape of the tensor from the flattened layer will be (batch_size, 18432,). Next, add a dense layer with 1024 neurons and LeakyReLU with alpha 0.2 as the activation function: dis_model.add(Dense(1024)) dis_model.add(LeakyReLU(alpha=0.2)) Finally, add a dense layer with one neuron for binary classification. The sigmoid function is the best for binary classification, as it gives the probability of the classes: dis_model.add(Dense(1)) dis_model.add(Activation('tanh')) The network will generate an output tensor of a shape of (batch_size, 1). The output tensor contains the probability of the classes. The complete code for the discriminator network wrapped inside a Python method looks as follows: def get_discriminator(): dis_model = Sequential() dis_model.add( Conv2D(128, (5, 5), padding='same', input_shape=(64, 64, 3)) ) dis_model.add(LeakyReLU(alpha=0.2)) dis_model.add(MaxPooling2D(pool_size=(2, 2))) dis_model.add(Conv2D(256, (3, 3))) dis_model.add(LeakyReLU(alpha=0.2)) dis_model.add(MaxPooling2D(pool_size=(2, 2))) dis_model.add(Conv2D(512, (3, 3))) dis_model.add(LeakyReLU(alpha=0.2)) dis_model.add(MaxPooling2D(pool_size=(2, 2))) dis_model.add(Flatten()) dis_model.add(Dense(1024)) dis_model.add(LeakyReLU(alpha=0.2)) dis_model.add(Dense(1)) dis_model.add(Activation('sigmoid')) return dis_model In this section, we have successfully implemented the discriminator and generator networks. Next, we will train the model on the dataset that we prepared in the Downloading and preparing the anime characters dataset section. Training the DCGAN Again, training a DCGAN is similar to training a Vanilla GAN network. It is a four-step process: Load the dataset. Build and compile the networks. Train the discriminator network. Train the generator network. We will work on these steps one by one in this section. Let's start by defining the variables and the hyperparameters: dataset_dir = "/Path/to/dataset/directory/*.*" batch_size = 128 z_shape = 100 epochs = 10000 dis_learning_rate = 0.0005 gen_learning_rate = 0.0005 dis_momentum = 0.9 gen_momentum = 0.9 dis_nesterov = True gen_nesterov = True Here, we have specified different hyperparameters for the training. We will now see how to load the dataset for the training. Loading the samples To train the DCGAN network, we need to load the dataset in memory and we need to define a mechanism to load batches of memory. Perform the following steps to load the dataset: Start by loading all images that you cropped, resized, and saved in the cropped folder. Specify the path of the directory correctly, so that the glob.glob method can create a list of all files in it. To read an image, use the imread method from the scipy.misc module. The following code shows the different steps to load all images inside the directory: # Loading images all_images = [] for index, filename in enumerate(glob.glob('/Path/to/cropped/images/directory/*.*')): image = imread(filename, flatten=False, mode='RGB') all_images.append(image) Next, create a ndarray of all the images. The shape of the final ndarray will be (total_num_images, 64, 64, 3). Also, normalize all the images: # Convert to Numpy ndarray X = np.array(all_images) X = (X - 127.5) / 127.5 Now we have loaded the dataset, next we will see how to build and compile the networks. Building and compiling the networks In this section, we will build and compile our networks required for the training: Start by defining the optimizers required for the training, as shown here: # Define optimizers dis_optimizer = SGD(lr=dis_learning_rate, momentum=dis_momentum, nesterov=dis_nesterov) gen_optimizer = SGD(lr=gen_learning_rate, momentum=gen_momentum, nesterov=gen_nesterov) Next, create an instance of the generator model, and compile the generator model (compiling will initialize the weights parameters, the optimizer algorithm, the loss function, and other essential steps required to use the network): gen_model = build_generator() gen_model.compile(loss='binary_crossentropy', optimizer=gen_optimizer) Use binary_crossentropy as the loss function for the generator networks and gen_optimizer as the optimizer. Next, create an instance of the discriminator model, and compile it, as shown here: dis_model = build_discriminator() dis_model.compile(loss='binary_crossentropy', optimizer=dis_optimizer) Similarly, use binary_crossentropy as the loss function for the discriminator network and  dis_optimizer as the optimizer. Next, create an adversarial model. An adversarial contains both networks in a single model. The architecture of the adversarial model will be as follows: input -> generator->discriminator->output The code to create and compile an adversarial model is as follows: adversarial_model = Sequential() adversarial_model.add(gen_model) dis_model.trainable = False adversarial_model.add(dis_model) When we train this network, we don't want to train the discriminator network, so make it non-trainable before we add it to the adversarial model. Compile the adversarial model, as follows: adversarial_model.compile(loss='binary_crossentropy', optimizer=gen_optimizer) Use binary_crossentropy as the loss function and gen_optimizer as the optimizer for the adversarial model. Before starting the training, add TensorBoard to visualize the losses, as follows: tensorboard = TensorBoard(log_dir="logs/{}".format(time.time()), write_images=True, write_grads=True, write_graph=True) tensorboard.set_model(gen_model) tensorboard.set_model(dis_model) We will train the network for a specified number of iterations, so create a loop that should run for a specified number of epochs. Inside each epoch, we will train our networks on a mini-batch of a size of 128. Calculate the number of batches that need to be processed: for epoch in range(epcohs): print("Epoch is", epoch) number_of_batches = int(X.shape[0] / batch_size) print("Number of batches", number_of_batches) for index in range(number_of_batches): We will now take a closer look at the training process. The following points explain the different steps involved in the training of DCGAN: Initially, both of the networks are naive and have random weights. The standard process to train a DCGAN network is to first train the discriminator on the batch of samples. To do this, we need fake samples as well as real samples. We already have the real samples, so we now need to generate the fake samples. To generate fake samples, create a latent vector of a shape of (100,) over a uniform distribution. Feed this latent vector to the untrained generator network. The generator network will generate fake samples that we use to train our discriminator network. Concatenate the real images and fake images to create a new set of sample images. We also need to create an array of labels: label 1 for real images and label 0 for fake images. Training the discriminator network Perform the following steps to train the discriminator network: Start by sampling a batch of noise vectors from a normal distribution, as follows: z_noise = np.random.normal(0, 1, size=(batch_size, z_shape)) To sample the values, use the normal() method from the np.random module in the Numpy library. Next, sample a batch of real images from the set of all images: image_batch = X[index * batch_size:(index + 1) * batch_size] Next, generate a batch of fake images using the generator network: generated_images = gen_model.predict_on_batch(z_noise) Next, create real labels and fake labels: y_real = np.ones(batch_size) - np.random.random_sample(batch_size) * 0.2 y_fake = np.random.random_sample(batch_size) * 0.2 Next, train the discriminator network on real images and real labels: dis_loss_real = dis_model.train_on_batch(image_batch, y_real) Similarly, train it on fake images and fake labels: dis_loss_fake = dis_model.train_on_batch(generated_images, y_fake) Next, calculate the average loss and print it to the console: d_loss = (dis_loss_real+dis_loss_fake)/2 print("d_loss:", d_loss) Up until now, we have been training the discriminator network. In the next section, let's train the generator network. Training the generator network To train the generator network, we have to train the adversarial model. When we train the adversarial model, it trains the generator network only but freezes the discriminator network. We won't train the discriminator network, as we have already trained it. Perform the following steps to train the adversarial model: Start by creating a batch of noise vectors again. Sample these noise vectors from a Gaussian/Normal distribution: z_noise = np.random.normal(0, 1, size=(batch_size, z_shape)) Next, train the adversarial model on this batch of noise vectors, as follows: g_loss = adversarial_model.train_on_batch(z_noise, [1] * batch_size) We train the adversarial model on the batch of noise vectors and real labels. Here, real labels is a vector with all values equal to 1. We are also training the generator to fool the discriminator network. To do this, we provide it with a vector that has all the values equal to 1. In this step, the generator will receive feedback from the generator network and improve itself accordingly. Finally, print the generator loss to the console to keep track of the losses: print("g_loss:", g_loss) There is a passive method to evaluate the training process. After every 10 epochs, generate fake images and manually check the quality of the images: if epoch % 10 == 0: z_noise = np.random.normal(0, 1, size=(batch_size, z_shape)) gen_images1 = gen_model.predict_on_batch(z_noise) for img in gen_images1[:2]: save_rgb_img(img, "results/one_{}.png".format(epoch)) These images will help you to decide whether to continue the training or to stop it early. Stop the training if quality of the generated high-resolution images is good; else, continue the training until your model becomes good. After this step, we then further evaluate the trained model and visualize the generated images. We have successfully trained a DCGAN network on the ANIME character dataset. Now we can use the model to generate images of anime characters. To summarize, in this tutorial, we looked at the different steps required to download and prepare the dataset. We then prepared a Keras implementation of the network and trained it on our dataset. If you enjoyed the tutorial and want to explore how to further evaluate the trained model, and optimize the networks by optimizing the hyperparameters, be sure to check out the book 'Generative Adversarial Networks Projects'. Generative Adversarial Networks: Generate images using Keras GAN [Tutorial] What you need to know about Generative Adversarial Networks Generative Adversarial Networks (GANs): The next milestone In Deep Learning
Read more
  • 0
  • 0
  • 31469
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-using-srgans-to-generate-photo-realistic-images-tutorial
Natasha Mathur
18 Apr 2019
16 min read
Save for later

Using SRGANs to Generate Photo-realistic Images [Tutorial]

Natasha Mathur
18 Apr 2019
16 min read
Super-Resolution Generative Adversarial Network, or SRGAN, is a Generative Adversarial Network (GAN) that can generate super-resolution images from low-resolution images, with finer details and higher quality. CNNs were earlier used to produce high-resolution images that train quicker and achieve high-level accuracy. However, in some cases, they are incapable of recovering finer details and often generate blurry images. In this tutorial, we will learn how to implement an SRGAN network in the Keras framework that will be capable of generating high-resolution images.  SRGANs were introduced in the paper titled, Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network, by Christian Ledig, Lucas Theis, Ferenc Huszar, Jose Caballero, Andrew Cunningham, and others. This tutorial is an excerpt taken from the book Generative Adversarial Networks Projects written by Kailash Ahirwar. The book explores unsupervised techniques for training neural networks and includes seven end-to-end projects in the GAN domain. Downloading the CelebA dataset For this tutorial, we will use the large-scale CelebFaces Attributes (CelebA) dataset, which is available here. The dataset contains 202, 599 face images of celebrities. The dataset is available for non-commercial research purposes only and can't be used for commercial purposes. If you intend to use the dataset for commercial purposes, seek permissions from the owners of the images. We will use the CelebA dataset to train our SRGAN network. Perform the following steps to download and extract the dataset: Download the dataset from the following link: https://www.dropbox.com/sh/8oqt9vytwxb3s4r/AAB06FXaQRUNtjW9ntaoPGvCa?dl=0 Extract images from the downloaded img_align_celeba.zip by executing the following command: unzip img_align_celeba.zip We have now downloaded and extracted the dataset. We can now start working on the Keras implementation of SRGAN. The Keras implementation of SRGAN SRGAN has three neural networks, a generator, a discriminator, and a pre-trained VGG19 network on the Imagenet dataset. In this section, we will write the implementation for all the networks. Let's start by implementing the generator network. Before starting to write the implementations, create a Python file called main.py and import the essential modules, as follows: import glob import os import numpy as np import tensorflow as tf from keras import Input from keras.applications import VGG19 from keras.callbacks import TensorBoard from keras.layers import BatchNormalization, Activation, LeakyReLU, Add, Dense, PReLU, Flatten from keras.layers.convolutional import Conv2D, UpSampling2D from keras.models import Model from keras.optimizers import Adam from keras_preprocessing.image import img_to_array, load_img from scipy.misc import imsave The generator network Let's start by writing the layers for the generator network in the Keras framework and then create a Keras model, using the functional API of the Keras framework. Perform the following steps to implement the generator network in Keras: Start by defining the hyperparameters required for the generator network: residual_blocks = 16 momentum = 0.8 input_shape = (64, 64, 3) Next, create an input layer to feed input to the network, as follows: input_layer = Input(shape=input_shape) The input layer takes an input image of a shape of (64, 64, 3) and passes it to the next layer in the network. Next, add the pre-residual block (2D convolution layer), as follows: Configuration: Filters: 64 Kernel size: 9 Strides: 1 Padding: same Activation: relu: gen1 = Conv2D(filters=64, kernel_size=9, strides=1, padding='same', activation='relu')(input_layer) Next, write a method with the entire code for the residual block, as shown here: def residual_block(x): """ Residual block """ filters = [64, 64] kernel_size = 3 strides = 1 padding = "same" momentum = 0.8 activation = "relu" res = Conv2D(filters=filters[0], kernel_size=kernel_size, strides=strides, padding=padding)(x) res = Activation(activation=activation)(res) res = BatchNormalization(momentum=momentum)(res) res = Conv2D(filters=filters[1], kernel_size=kernel_size, strides=strides, padding=padding)(res) res = BatchNormalization(momentum=momentum)(res) # Add res and x res = Add()([res, x]) return res Now, add 16 residual blocks using the residual_block function, defined in the last step: res = residual_block(gen1) for i in range(residual_blocks - 1): res = residual_block(res) The output of the pre-residual block goes to the first residual block. The output of the first residual block goes to the second residual block, and so on, up to the 16th residual block. Next, add the post-residual block (a 2D convolution layer followed by a batch normalization layer), as follows: Configuration: Filters: 64 Kernel size: 3 Strides: 1 Padding: same Batchnormalization: Yes (momentum=0.8): gen2 = Conv2D(filters=64, kernel_size=3, strides=1, padding='same')(res) gen2 = BatchNormalization(momentum=momentum)(gen2) Now, add an Add layer to take the sum of the output from the pre-residual block, which is gen1, and the output from the post-residual block, which is gen2. This layer generates another tensor of similar shape. gen3 = Add()([gen2, gen1]) Next, add an upsampling block, as follows: Configuration: Upsampling size: 2 Filers: 256 Kernel size: 3 Strides: 1 Padding: same Activation: PReLU: gen4 = UpSampling2D(size=2)(gen3) gen4 = Conv2D(filters=256, kernel_size=3, strides=1, padding='same')(gen4) gen4 = Activation('relu')(gen4) Next, add another upsampling block, as follows: Configuration: Upsampling size: 2 Filers: 256 Kernel size: 3 Strides: 1 Padding: same Activation: PReLU: gen5 = UpSampling2D(size=2)(gen4) gen5 = Conv2D(filters=256, kernel_size=3, strides=1, padding='same')(gen5) gen5 = Activation('relu')(gen5) Finally, add the output convolution layer: Configuration: Filters: 3 (equal to number of channels) Kernel size: 9 Strides: 1 Padding: same Activation: tanh: gen6 = Conv2D(filters=3, kernel_size=9, strides=1, padding='same')(gen5) output = Activation('tanh')(gen6) Once you have defined all the layers in the network, you can create a Keras model. We have defined a Keras sequential graph using Keras's functional API. Let's create a Keras model by specifying the input and output for the network. Now, create a Keras model and specify the inputs and the outputs for the model, as follows: model = Model(inputs=[input_layer], outputs=[output], name='generator') We have successfully created a Keras model for the generator network. Now wrap the entire code for the generator network inside a Python function, as follows: def build_generator(): """ Create a generator network using the hyperparameter values defined below :return: """ residual_blocks = 16 momentum = 0.8 input_shape = (64, 64, 3) # Input Layer of the generator network input_layer = Input(shape=input_shape) # Add the pre-residual block gen1 = Conv2D(filters=64, kernel_size=9, strides=1, padding='same', activation='relu')(input_layer) # Add 16 residual blocks res = residual_block(gen1) for i in range(residual_blocks - 1): res = residual_block(res) # Add the post-residual block gen2 = Conv2D(filters=64, kernel_size=3, strides=1, padding='same')(res) gen2 = BatchNormalization(momentum=momentum)(gen2) # Take the sum of the output from the pre-residual block(gen1) and the post-residual block(gen2) gen3 = Add()([gen2, gen1]) # Add an upsampling block gen4 = UpSampling2D(size=2)(gen3) gen4 = Conv2D(filters=256, kernel_size=3, strides=1, padding='same')(gen4) gen4 = Activation('relu')(gen4) # Add another upsampling block gen5 = UpSampling2D(size=2)(gen4) gen5 = Conv2D(filters=256, kernel_size=3, strides=1, padding='same')(gen5) gen5 = Activation('relu')(gen5) # Output convolution layer gen6 = Conv2D(filters=3, kernel_size=9, strides=1, padding='same')(gen5) output = Activation('tanh')(gen6) # Keras model model = Model(inputs=[input_layer], outputs=[output], name='generator') return model We have successfully created a Keras model for the generator network. In the next section, we will create a Keras model for the discriminator network. The discriminator network Let's start by writing the layers for the discriminator network in the Keras framework and then create a Keras model, using the functional API of the Keras framework. Perform the following steps to implement the discriminator network in Keras: Start by defining the hyperparameters required for the discriminator network: leakyrelu_alpha = 0.2 momentum = 0.8 input_shape = (256, 256, 3) Next, create an input layer to feed input to the network, as follows: input_layer = Input(shape=input_shape) Next, add a convolution block, as follows: Configuration: Filters: 64 Kernel size: 3 Strides: 1 Padding: same Activation: LeakyReLU with alpha equal to 0.2: dis1 = Conv2D(filters=64, kernel_size=3, strides=1, padding='same')(input_layer) dis1 = LeakyReLU(alpha=leakyrelu_alpha)(dis1) Next, add another seven convolution blocks, as follows: Configuration: Filters: 64, 128, 128, 256, 256, 512, 512 Kernel size: 3, 3, 3, 3, 3, 3, 3 Strides: 2, 1, 2, 1, 2, 1, 2 Padding: same for each convolution layer Activation: LealyReLU with alpha equal to 0.2 for each convolution layer: # Add the 2nd convolution block dis2 = Conv2D(filters=64, kernel_size=3, strides=2, padding='same')(dis1) dis2 = LeakyReLU(alpha=leakyrelu_alpha)(dis2) dis2 = BatchNormalization(momentum=momentum)(dis2) # Add the third convolution block dis3 = Conv2D(filters=128, kernel_size=3, strides=1, padding='same')(dis2) dis3 = LeakyReLU(alpha=leakyrelu_alpha)(dis3) dis3 = BatchNormalization(momentum=momentum)(dis3) # Add the fourth convolution block dis4 = Conv2D(filters=128, kernel_size=3, strides=2, padding='same')(dis3) dis4 = LeakyReLU(alpha=leakyrelu_alpha)(dis4) dis4 = BatchNormalization(momentum=0.8)(dis4) # Add the fifth convolution block dis5 = Conv2D(256, kernel_size=3, strides=1, padding='same')(dis4) dis5 = LeakyReLU(alpha=leakyrelu_alpha)(dis5) dis5 = BatchNormalization(momentum=momentum)(dis5) # Add the sixth convolution block dis6 = Conv2D(filters=256, kernel_size=3, strides=2, padding='same')(dis5) dis6 = LeakyReLU(alpha=leakyrelu_alpha)(dis6) dis6 = BatchNormalization(momentum=momentum)(dis6) # Add the seventh convolution block dis7 = Conv2D(filters=512, kernel_size=3, strides=1, padding='same')(dis6) dis7 = LeakyReLU(alpha=leakyrelu_alpha)(dis7) dis7 = BatchNormalization(momentum=momentum)(dis7) # Add the eight convolution block dis8 = Conv2D(filters=512, kernel_size=3, strides=2, padding='same')(dis7) dis8 = LeakyReLU(alpha=leakyrelu_alpha)(dis8) dis8 = BatchNormalization(momentum=momentum)(dis8) Next, add a dense layer with 1,024 nodes, as follows: Configuration: Nodes: 1024 Activation: LeakyReLU with alpha equal to 0.2: dis9 = Dense(units=1024)(dis8) dis9 = LeakyReLU(alpha=0.2)(dis9) Then, add a dense layer to return the probabilities, as follows: output = Dense(units=1, activation='sigmoid')(dis9) Finally, create a Keras model and specify the inputs and the outputs for the network: model = Model(inputs=[input_layer], outputs=[output], name='discriminator') Wrap the entire code for the discriminator network inside a function, as follows: def build_discriminator(): """ Create a discriminator network using the hyperparameter values defined below :return: """ leakyrelu_alpha = 0.2 momentum = 0.8 input_shape = (256, 256, 3) input_layer = Input(shape=input_shape) # Add the first convolution block dis1 = Conv2D(filters=64, kernel_size=3, strides=1, padding='same')(input_layer) dis1 = LeakyReLU(alpha=leakyrelu_alpha)(dis1) # Add the 2nd convolution block dis2 = Conv2D(filters=64, kernel_size=3, strides=2, padding='same')(dis1) dis2 = LeakyReLU(alpha=leakyrelu_alpha)(dis2) dis2 = BatchNormalization(momentum=momentum)(dis2) # Add the third convolution block dis3 = Conv2D(filters=128, kernel_size=3, strides=1, padding='same')(dis2) dis3 = LeakyReLU(alpha=leakyrelu_alpha)(dis3) dis3 = BatchNormalization(momentum=momentum)(dis3) # Add the fourth convolution block dis4 = Conv2D(filters=128, kernel_size=3, strides=2, padding='same')(dis3) dis4 = LeakyReLU(alpha=leakyrelu_alpha)(dis4) dis4 = BatchNormalization(momentum=0.8)(dis4) # Add the fifth convolution block dis5 = Conv2D(256, kernel_size=3, strides=1, padding='same')(dis4) dis5 = LeakyReLU(alpha=leakyrelu_alpha)(dis5) dis5 = BatchNormalization(momentum=momentum)(dis5) # Add the sixth convolution block dis6 = Conv2D(filters=256, kernel_size=3, strides=2, padding='same')(dis5) dis6 = LeakyReLU(alpha=leakyrelu_alpha)(dis6) dis6 = BatchNormalization(momentum=momentum)(dis6) # Add the seventh convolution block dis7 = Conv2D(filters=512, kernel_size=3, strides=1, padding='same')(dis6) dis7 = LeakyReLU(alpha=leakyrelu_alpha)(dis7) dis7 = BatchNormalization(momentum=momentum)(dis7) # Add the eight convolution block dis8 = Conv2D(filters=512, kernel_size=3, strides=2, padding='same')(dis7) dis8 = LeakyReLU(alpha=leakyrelu_alpha)(dis8) dis8 = BatchNormalization(momentum=momentum)(dis8) # Add a dense layer dis9 = Dense(units=1024)(dis8) dis9 = LeakyReLU(alpha=0.2)(dis9) # Last dense layer - for classification output = Dense(units=1, activation='sigmoid')(dis9) model = Model(inputs=[input_layer], outputs=[output], name='discriminator') return model In this section, we have successfully created a Keras model for the discriminator network. The adversarial network The adversarial network is a combined network that uses the generator, the discriminator, and VGG19. In this section, we will create an adversarial network. Perform the following steps to create an adversarial network: Start by creating an input layer for the network: input_low_resolution = Input(shape=(64, 64, 3)) The adversarial network will receive an image of a shape of (64, 64, 3), which is why we have created an input layer. Next, generate fake high-resolution images using the generator network, as follows: fake_hr_images = generator(input_low_resolution) Next, extract the features of the fake images using the VGG19 network, as follows: fake_features = vgg(fake_hr_images) Next, make the discriminator network non-trainable in the adversarial network: discriminator.trainable = False We are making the discriminator network non-trainable because we don't want to train the discriminator network while we train the generator network. Next, pass the fake images to the discriminator network: output = discriminator(fake_hr_images) Finally, create a Keras model, which will be our adversarial model: model = Model(inputs=[input_low_resolution], outputs=[output, fake_features]) Wrap the entire code for the adversarial model inside a Python function: def build_adversarial_model(generator, discriminator, vgg): input_low_resolution = Input(shape=(64, 64, 3)) fake_hr_images = generator(input_low_resolution) fake_features = vgg(fake_hr_images) discriminator.trainable = False output = discriminator(fake_hr_images) model = Model(inputs=[input_low_resolution], outputs=[output, fake_features]) for layer in model.layers: print(layer.name, layer.trainable) print(model.summary()) return model We have now successfully implemented the networks in Keras. Next, we train the network on the dataset that we downloaded. Training the SRGAN Training the SRGAN network is a two-step process. In the first step, we train the discriminator network. In the second step, we train the adversarial network, which eventually trains the generator network. Let's start training the network. Perform the following steps to train the SRGAN network: Start by defining the hyperparameters required for the training: # Define hyperparameters data_dir = "Paht/to/the/dataset/img_align_celeba/*.*" epochs = 20000 batch_size = 1 # Shape of low-resolution and high-resolution images low_resolution_shape = (64, 64, 3) high_resolution_shape = (256, 256, 3) Next, define the training optimizer. For all networks, we will use Adam optimizer with the learning rate equal to 0.0002 and beta_1 equal to 0.5: # Common optimizer for all networks common_optimizer = Adam(0.0002, 0.5) Building and compiling the networks In this section, we will go through the different steps required to build and compile the networks: Build and compile the VGG19 network: vgg = build_vgg() vgg.trainable = False vgg.compile(loss='mse', optimizer=common_optimizer, metrics= ['accuracy']) To compile VGG19, use mse as the loss, accuracy as the metrics, and common_optimizer as the optimizer. Before compiling the network, disable the training, as we don't want to train the VGG19 network. Next, build and compile the discriminator network, as follows: discriminator = build_discriminator() discriminator.compile(loss='mse', optimizer=common_optimizer, metrics=['accuracy']) To compile the discriminator network, use mse as the loss, accuracy as the metrics, and common_optimizer as the optimizer. Next, build the generator network: generator = build_generator() Next, create an adversarial model. Start by creating two input layers: input_high_resolution = Input(shape=high_resolution_shape) input_low_resolution = Input(shape=low_resolution_shape) Next, use the generator network to symbolically generate high-resolution images from the low-resolution images: generated_high_resolution_images = generator(input_low_resolution) Use VGG19 to extract feature maps for the generated images: features = vgg(generated_high_resolution_images) Make the discriminator network non-trainable, because we don't want to train the discriminator model during the training of the adversarial model: discriminator.trainable = False Next, use the discriminator network to get the probabilities of the generated high-resolution fake images: probs = discriminator(generated_high_resolution_images) Here, probs represent the probability of the generated images belonging to a real dataset. Finally, create and compile the adversarial network: adversarial_model = Model([input_low_resolution, input_high_resolution], [probs, features]) adversarial_model.compile(loss=['binary_crossentropy', 'mse'], loss_weights=[1e-3, 1], optimizer=common_optimizer) To compile the adversarial model, use binary_crossentropy and mse as the loss functions, common_optimizer as the optimizer, and [0.001, 1] as the loss weights. Add Tensorboard to visualize the training losses and to visualize the network graphs: tensorboard = TensorBoard(log_dir="logs/".format(time.time())) tensorboard.set_model(generator) tensorboard.set_model(discriminator) Create a loop that should run for the specified number of epochs: for epoch in range(epochs): print("Epoch:{}".format(epoch)) After this step, all of the code will be inside this for loop. Next, sample a batch of high-resolution and low-resolution images, as follows: high_resolution_images, low_resolution_images = sample_images(data_dir=data_dir, batch_size=batch_size,low_resolution_shape=low_resolution_shape, high_resolution_shape=high_resolution_shape) The code for the sample_images function is as follows. It is quite descriptive and can be understood by going through it. It contains different steps to load and resize the images to generate high-resolution as well as low-resolution images: def sample_images(data_dir, batch_size, high_resolution_shape, low_resolution_shape): # Make a list of all images inside the data directory all_images = glob.glob(data_dir) # Choose a random batch of images images_batch = np.random.choice(all_images, size=batch_size) low_resolution_images = [] high_resolution_images = [] for img in images_batch: # Get an ndarray of the current image img1 = imread(img, mode='RGB') img1 = img1.astype(np.float32) # Resize the image img1_high_resolution = imresize(img1, high_resolution_shape) img1_low_resolution = imresize(img1, low_resolution_shape) # Do a random flip if np.random.random() < 0.5: img1_high_resolution = np.fliplr(img1_high_resolution) img1_low_resolution = np.fliplr(img1_low_resolution) high_resolution_images.append(img1_high_resolution) low_resolution_images.append(img1_low_resolution) return np.array(high_resolution_images), np.array(low_resolution_images) Next, normalize the images to convert the pixel values to a range between [-1, 1], as follows: high_resolution_images = high_resolution_images / 127.5 - 1. low_resolution_images = low_resolution_images / 127.5 - 1. It is very important to convert the pixel values to a range of between -1 to 1. Our generator network has tanh at the end of the network. The tanh activation function squashes values to the same range. While calculating the loss, it is necessary to have all values in the same range. After this step is complete, we train the discriminator network, generator network, and then further visualize the images and evaluate the model. In this tutorial, we learned how to download the CelebA dataset, and implemented the project in Keras before training the SRGAN.  If you want to learn more about how to evaluate the trained SRGAN network, and optimizing the trained model, be sure to check out the book Generative Adversarial Networks Projects. Generative Adversarial Networks: Generate images using Keras GAN [Tutorial] What you need to know about Generative Adversarial Networks Generative Adversarial Networks (GANs): The next milestone In Deep Learning
Read more
  • 0
  • 0
  • 23618

article-image-jack-dorsey-engaged-in-another-tonedeaf-public-conversation-to-better-twitter
Fatema Patrawala
17 Apr 2019
7 min read
Save for later

Jack Dorsey engages in yet another tone deaf "public conversation" to better Twitter

Fatema Patrawala
17 Apr 2019
7 min read
What if you created something that allowed people to make fun of you? Such is the life and career of Jack Dorsey, co-founder and CEO of Twitter. Yesterday the tech guru did a TED Talk public conversation with the head of TED, Chris Anderson, and Whitney Pennington Rodgers, TED’s current affairs curator. The major part of the whole conversation involved around the recent “concerns and opportunities for Twitter’s future.” For most of the interview, Dorsey outlined steps that Twitter has taken to combat abuse and misinformation, and Anderson explained why the company’s critics sometimes find those steps insufficient and unsatisfying. He compared Twitter to the Titanic, and Dorsey to the captain, listening to passengers’ concerns about the iceberg up ahead — then going back to the bridge and showing “this extraordinary calm.” “It’s democracy at stake, it’s our culture at stake,” Anderson said, echoing points made in a talk by British journalist Carole Cadwalladr. So why isn’t Twitter addressing these issues with more urgency? “We are working as quickly as we can, but quickness will not get the job done,” Dorsey replied to Anderson. “It’s focus, it’s prioritization, it’s understanding the fundamentals of the network.” Jack further argued that while Twitter could “do a bunch of superficial things to address the things you’re talking about,” that isn’t the real solution. “We want the changes to last, and that means going really, really deep,” Dorsey said. In his view, that means rethinking how Twitter incentivizes user behavior. He suggested that the service works best as an “interest-based network,” where you log in and see content relevant to your interests, no matter who posted it — rather than a network where everyone feels like they need to follow a bunch of other accounts, and then grow their follower numbers in turn. Dorsey recalled that when the team was first building the service, it decided to make follower count “big and bold,” which naturally made people focus on it. “Was that the right decision at the time? Probably not,” he said. “If I had to start the service again, I would not emphasize the follower count as much... Since he isn’t starting from scratch, Dorsey suggested that he’s trying to find ways to redesign Twitter to shift the “bias” away from accounts and toward interests. He also pointed to efforts that Twitter has already announced to measure (and then improve) conversational health and to use machine learning to automatically detect abusive content. In terms of how the company is currently measuring its success, Dorsey said it focuses primarily on daily active users, and secondly on “conversation chains — we want to incentivize healthy contributions back to the network.” In contradiction to his response when over the weekend, Ilhan Omar an immigrant, and a Black Muslim representing the state of Minnesota in the US House of representatives —reported an increase in death threats. The threats started appearing after President Trump tweeted out a video that intercut a speech she had given with footage of the 9/11 attacks. Many of the threats were made on Twitter. Then on Monday, as Notre Dame burned, people came to the platform to mourn the loss in real time, but also to spread lies and hate as quickly as the flames engulfed the cathedral’s spire. When Omar tweeted her own heartfelt condolences, people replied with more death threats. Dorsey didn’t address any of these incidents specifically at TED. In fact, his answers lacked specificity overall. One Twitter user, Chad Loder created a Twitter moment to stand with Ilhan Omar. He asked users to report all the tweets with death threats to Ilhan. To this Twitter safety team removed all the tweets in just 30 minutes and he could not further add any tweets. https://twitter.com/chadloder/status/1118287939220336640 When Jack was asked pointed questions, he evaded them, as he often does. Rodgers further asked him how many people are working on content moderation on Twitter—a number the company has never published. “It varies,” Dorsey replied. “We want to be flexible on this. There are no amount of people that can actually scale this, which is why we have done so much work on proactively taking down abuse.” Dorsey further announced that a year ago, Twitter wasn’t proactively monitoring abuse actively using machine learning at all. Instead, it relied entirely on human reporting—a burden Dorsey later had to recognized was unfairly put on the victims of the abuse. “We’ve made progress,” he said. “Thirty-eight percent of abusive tweets are now proactively recognized by machine-learning algorithms, but those that are recognized are still reviewed by humans. But that was from zero percent just a year ago.” As he uttered those words, Twitter sent out a press release with more information on the effort, highlighting that three times more abusive accounts are being suspended within 24 hours of getting reported compared with this time last year. The progress of 38% is not exactly a lot when Facebook’s most recent transparency report, says that over 51% of content on hate speech was flagged before users reported it. Nor did Dorsey or the official Twitter announcement provide many details about how the technology to proactively flag abuse works. While the conversations continued, they came up with an idea to invite Twitter users to tweet questions via the hashtag #AskJackAtTED, which was then projected on a big screen behind Dorsey. Looking at all the tweets coming up live it seemed to be a really bad idea. https://twitter.com/TEDTalks/status/1118182843354701826 In Twitter spirit, sarcastic piercing tweets soon overflowed on the screen asking Dorsey crisp pointed questions about long pending failures to make the platform a safe place for healthy conversation. Users charged Dorsey left, right and centre with questions. Carole Cadwalladr asked why a video that showed her being beaten up & threatened with a gun to soundtrack of Russian anthem stayed up for 72 hours despite 1000s of complaints. Other came up saying how do you prioritize healthy conversations without silencing protest on your platform? https://twitter.com/carolecadwalla/status/1118184265781587968 https://twitter.com/jonnysun/status/1118190191066398720 Tweets continued pouring in with questions like why is women harassment on the platform ignored for decades and why do you still allow Nazi groups on Twitter. https://twitter.com/beccalew/status/1118194017840144386 https://twitter.com/chick_in_kiev/status/1118208375534362624 One of them asked if there was anyway to add a fact-check function to viral tweets which involves misinformation or conspiracy theories. https://twitter.com/MollyJongFast/status/1118185171860303873 Another popular tweet said it wants Twitter to create a user bill where they have the right to be free of harassment and the right to safety. https://twitter.com/RedTRaccoon/status/1118256403498577920 https://twitter.com/olmaverick/status/1118186175364075521 https://twitter.com/baratunde/status/1118186537215094785 https://twitter.com/johnbattelle/status/1118185819691528197 https://twitter.com/MaraWilson/status/1118190714494410752 While some users said that Twitter is of no value at all others raised questions on why does the platform allow the organizers of Charlottesville disaster amplify their message and find new recruits. Another added why is President Donald Trump allowed to violate Twitter policies by spreading hateful and inflammatory tweets against Ilhan Omar. https://twitter.com/Bro_Pair/status/1118186479048478725 https://twitter.com/WajahatAli/status/1118183456985448450 https://twitter.com/brosandprose/status/1118185344397082625 Eventually the tweets disappeared from the screen and someone from the audience made a suspicion that it was always a plan to ditch in between. On the other hand Anderson summed it up sarcastically: “We are on this great voyage with you on a ship, and there are people on board in steerage who are expressing discomfort and you, unlike other captains are saying, ‘well, tell me, I want to hear,’ and they’re saying ‘we’re worried about the iceberg ahead,'” Anderson says. “And you say, ‘our ship hasn’t been built for steering as well as it might,’ and you’re showing this extraordinary calm!” Highlights from Jack Dorsey’s live interview by Kara Swisher on Twitter: on lack of diversity, tech responsibility, physical safety and more Russia opens civil cases against Facebook and Twitter over local data laws Twitter memes are being used to hide malware
Read more
  • 0
  • 0
  • 8831

article-image-eu-approves-labour-protection-laws-for-whistleblowers-and-gig-economy-workers-with-implications-for-tech-companies
Savia Lobo
17 Apr 2019
5 min read
Save for later

EU approves labour protection laws for ‘Whistleblowers’ and ‘Gig economy’ workers with implications for tech companies

Savia Lobo
17 Apr 2019
5 min read
The European Union approved two new labour protection laws recently. This time, for the two not so hyped sects, the whistleblowers and the ones earning their income via the ‘gig economy’. As for the whistleblowers, with the new law, they receive an increased protection landmark legislation aimed at encouraging reports of wrongdoing. On the other hand, for those working for ‘on-demand’ jobs, thus, termed as the gig economy, the law sets minimum rights and demands increased transparency for such workers. Let’s have a brief look at each of the newly approved by the EU. Whistleblowers’ shield against retaliation On Tuesday, the EU parliament approved a new law for whistleblowers safeguarding them from any retaliation within an organization. The law protects whistleblowers against dismissal, demotion and other forms of punishment. “The law now needs to be approved by EU ministers. Member states will then have two years to comply with the rules”, the EU proposal states. Transparency International calls this as “pathbreaking legislation”, which will also give employees a "greater legal certainty around their rights and obligations". The new law creates a safe channel which allows the whistleblowers to report of an EU law breach both within an organization and to public authorities. “It is the first time whistleblowers have been given EU-wide protection. The law was approved by 591 votes, with 29 votes against and 33 abstentions”, the BBC reports. In cases where no appropriate action is taken by the organization’s authorities even after reporting, whistleblowers are allowed to make public disclosure of the wrongdoing by communicating with the media. European Commission Vice President, Frans Timmermans, says, “potential whistleblowers are often discouraged from reporting their concerns or suspicions for fear of retaliation. We should protect whistleblowers from being punished, sacked, demoted or sued in court for doing the right thing for society.” He further added, “This will help tackle fraud, corruption, corporate tax avoidance and damage to people's health and the environment.” “The European Commission says just 10 members - France, Hungary, Ireland, Italy, Lithuania, Malta, the Netherlands, Slovakia, Sweden, and the UK - had a "comprehensive law" protecting whistleblowers”, the BBC reports. “Attempts by some states to water down the reform earlier this year were blocked at an early stage of the talks with Luxembourg, Ireland, and Hungary seeking to have tax matters excluded. However, a coalition of EU states, including Germany, France, and Italy, eventually prevailed in keeping tax revelations within the proposal”, the Reuters report. “If member states fail to properly implement the law, the European Commission can take formal disciplinary steps against the country and could ultimately refer the case to the European Court of Justice”, BBC reports. To know more about this new law for whistleblowers, read the official proposal. EU grants protection to workers in Gig economy (casual or short-term employment) In a vote on Tuesday, the Members of the European Parliament (MEP) announced minimum rights for workers with on-demand, voucher-based or platform jobs, such as Uber or Deliveroo. However, genuinely self-employed workers would be excluded from the new rules. “The law states that every person who has an employment contract or employment relationship as defined by law, collective agreements or practice in force in each member state should be covered by these new rights”, BBC reports. “This would mean that workers in casual or short-term employment, on-demand workers, intermittent workers, voucher-based workers, platform workers, as well as paid trainees and apprentices, deserve a set of minimum rights, as long as they meet these criteria and pass the threshold of working 3 hours per week and 12 hours per 4 weeks on average”, according to EU’s official website. For this, all workers need to be informed from day one as a general principle, but no later than seven days where justified. Following are the specific set of rights to cover new forms of employment includes: Workers with on-demand contracts or similar forms of employment should benefit from a minimum level of predictability such as predetermined reference hours and reference days. They should also be able to refuse, without consequences, an assignment outside predetermined hours or be compensated if the assignment was not cancelled in time. Member states shall adopt measures to prevent abusive practices, such as limits to the use and duration of the contract. The employer should not prohibit, penalize or hinder workers from taking jobs with other companies if this falls outside the work schedule established with that employer. Enrique Calvet Chambon, the MEP responsible for seeing the law through, said, “This directive is the first big step towards the implementation of the European Pillar of Social Rights, affecting all EU workers. All workers who have been in limbo will now be granted minimum rights thanks to this directive, and the European Court of Justice rulings, from now on no employer will be able to abuse the flexibility in the labour market.” To know more about this new law on Gig economy, visit EU’s official website. 19 nations including The UK and Germany give thumbs-up to EU’s Copyright Directive Facebook discussions with the EU resulted in changes of its terms and services for users The EU commission introduces guidelines for achieving a ‘Trustworthy AI’
Read more
  • 0
  • 0
  • 3482

article-image-how-to-create-your-own-r-package-with-rstudio-tutorial
Natasha Mathur
17 Apr 2019
3 min read
Save for later

How to create your own R package with RStudio [Tutorial]

Natasha Mathur
17 Apr 2019
3 min read
In this tutorial, we will look at the process of creating your own R package. If you are going to create code and put it into production, it's always a good idea to create a package with version control, examples, and other features. Plus, with RStudio, it is easy to do. So, we will use a simple example with one small function to show how easy it is. This tutorial is an excerpt taken from the book Mastering Machine Learning with R - Third Edition written by Cory Lesmeister. The book explores expert techniques for solving data analytics and covers machine learning challenges that can help you gain insights from complex projects and power up your applications. Before getting started, you will need to load two packages: > install.packages("roxygen2") > install.packages("devtools") You now want to open File in RStudio and select New Project, which will put you at this point: Select a new directory as desired, and specify R Package, as shown in the following screenshot: You will now name your package – I've innovatively called this one package – and select Create Project: Go to your Files tab in RStudio and you should see several files populated like this: Notice the folder called R. That is where we will put the R functions for our package. But first, click on Description and fill it out accordingly, and save it. Here is my version, which will be a function to code all missing values in a dataframe to zero: I've left imports and suggests blank. This is where you would load other packages, such as tidyverse or caret. Now, open up the hello.R function in the R folder, and delete all of it. The following format will work nicely: Title: Your package title of course Description: A brief description Param: The parameters for that function; the arguments Return: The values returned Examples: Provide any examples of how to use the function Export: Here, write the function you desire Here is the function for our purposes, which just turns all NAs to zero: You will now go to Build - Configure Build Tools and you should end up here: Click the checkmark for Generate documentation with Roxygen. Doing so will create this popup, which you can close and hit OK. You probably want to rename your function now from hello.R to something relevant. Now comes the moment of truth to build your package. Do this by clicking Build - Clean and Rebuild. Now you can search for your package, and it should appear: Click on it and go through the documentation: There you have it, a useless package, but think of what you can do by packaging your own or your favorite functions, and anyone who inherits your code will thank you. In this tutorial, we went through the process of creating an R package, which can help you and your team put your code into production. We created one user-defined function for our package, but your only limit is your imagination. I hope you've enjoyed it and can implement the methods in here, as well as other methods you learn over time. If you want to learn other concepts of Machine Learning with R, be sure to check out the book Mastering Machine Learning with R - Third Edition. How to make machine learning based recommendations using Julia [Tutorial] The rise of machine learning in the investment industry GitHub Octoverse: top machine learning packages, languages, and projects of 2018
Read more
  • 0
  • 0
  • 52218
article-image-how-visual-studio-code-can-help-bridge-the-gap-between-full-stack-development-and-devops
Richard Gall
16 Apr 2019
8 min read
Save for later

How Visual Studio Code can help bridge the gap between full-stack development and DevOps [Sponsored by Microsoft]

Richard Gall
16 Apr 2019
8 min read
The popularity of Visual Studio Code is an indication of how the developer landscape is changing. It’s also a testament to the way the development team behind it have been proactive in responding to these changes and using them to inform iterations of the product. But what are these changes, exactly? Well, one way of understanding them is to focus on the growth of full-stack development as a job role. Thanks to cloud native and increased levels of abstraction across the stack, developers are being asked to do more. They’re not so much writing specialized code for the part of the stack that they ‘own’ in the way they might have been five years ago. Instead, a more holistic approach has become the norm. This post is part of a series brought to you in conjunction with Microsoft. Download Learning Node.js Development for free from Microsoft here. This holistic approach is one where developers assemble applications, with an even greater focus - and indeed deliberation - on matters of infrastructure and architecture. Shipping code is important, but there is more to development roles than simply producing the building blocks of software. A good full stack developer is one who can shift between contexts. This could be context shifting in a literal sense, but it might also more broadly mean shifting between different types of problems. Crucial to this is an in-built DevOps mindset. Siloed compartmentalization is the enemy of the modern developer in just about every respect. This is why Visual Studio Code is so valuable today. It tackles compartmentalization, helping developers move between different problems and contexts seamlessly. In turn, this bridges the gap between what we would typically consider a full-stack engineer role and responsibilities and those of a DevOps engineer. Read next: DevOps engineering and full-stack development – 2 sides of the same agile coin How does Visual Studio Code support a DevOps mindset? From writing and optimizing code, to deploying to the cloud and managing those resources in the cloud, Visual Studio allows developers to do multiple things easily. Let's take a look at some of the features of the editor (or IDE, depending on your perspective) to see what this means in practical terms. VSCode helps developers assume responsibility for how their code performs Code optimization becomes important when you really start to take the issue of accountability seriously. Yes, that could be frustrating (especially if you’re a bad developer…) but it also makes writing code much more interesting. And Visual Studio Code has tools that help you to do just that. Like a good and friendly DevOps engineer, the text editor has a set of in-built features and extensions that can help you write cleaner and more performant code. There are, of course, plenty of extensions to help improve code, but before we even get there, Visual Studio Code has out of the box features that can aid productivity. IntelliSense, for example, Microsoft’s useful autocomplete feature, takes some of the leg work out of writing code. But it’s once you get into the extensions that you can begin to see how much support Visual Studio Code can bring. IntelliSense has several useful extensions - one for npm, one for Node.js modules, for example, but there are plenty of other useful tools, from code snippets to Chrome Debugger and Prettier, an extension for the popular code formatter that has seen 5 million downloads in a matter of months. Individually these tools might not seem like a big deal. But it’s the fact that you have access to these various features - if you want them, of course - that marks VSC out as somewhere that wants you to be productive, that wants you to focus on code health. That’s not to say that Atom, emacs, or any other editor doesn’t do this - it’s just that VSC steps in and takes up and performs in lieu of your brain. Which means you can focus your mind elsewhere. VSCode has features that encourages really effective developer collaboration DevOps is, fundamentally, a methodology about the way people build software together. Conversely, code editors often feel like a personal decision - something as unique to you as any other piece of technology that allows you to interface with information and with other people. And although VSC can feel as personal as any code editor (check out the themes - Dracula is particularly lovely…), because it is more than a typical code editor, it offers plenty of ways to enhance project management and collaboration. Perhaps the most notable example of how Visual Studio Code supports collaboration is the Live Share extension.  This nifty extension allows you to work on code with a colleague working on a different machine, as if you were collaborating on a Word document. As well as being pretty novel, the implications of this could be greater than we realise. By making it easier to open up the way we work at a very individual - almost atomized level - the way we work together to build and deploy code immediately changes. Software engineering has always been a team sport but coding itself was all too often a solitary activity. With Live Share you can quite deliberately begin to break down silos in a way that you've never been able to do before. Okay, but what does Live Share really have to do with DevOps? Well, if we can improve collaboration between people, we can immediately cut through any residual siloes. But more than that, it also opens new work practices for the future. Pair Programming, for example, might feel like a bit of a flash in the plan programming practice, but the principles become the norm if its better facilitated. And while an individual agile technique certainly does not make DevOps magically happen, making it normal can go a long way in helping to improve code quality and accountability. Visual Studio Code brings the cloud to full-stack developers (and vice versa) Collaboration, productivity - great. Code optimization - also great. But if you really want to think about how Visual Studio Code bridges the gap between full-stack development and DevOps, you have to look at the ways in which it allows developers to leverage Azure. An article published by TechCrunch in 2016 argued that cloud - managed services - had ‘killed DevOps’. That might have been a bit of an overstatement, but if you follow the logic you can begin to see that the world is moving towards a world where cloud actually and supports and facilitates DevOps processes. It almost removes the need for a separate operations engineer to deploy your applications appropriately. But even if the lack of friction here is appealing, you will nevertheless to be open to a new way of working. And that is never straightforward. And that’s where Visual Studio Code can help. With Azure App Service or Azure Functions extensions, you can deploy and manage Azure resources directly from your editor. That’s a productivity bonus, but it also immediately makes the concept of cloud or serverless more accessible, especially if you’re new to it. In VSC you’re literally working with it in a familiar space. The conclusion of that TechCrunch article is instructive: “DevOps as a team may be gone sooner than later, but its practices will be carried on to whole development teams so that we can continue to build upon what it has brought us in the past years.” Arguably, Visual Studio Code is an editor that takes us to that point - one where DevOps practices are embedded in development teams. Visual Studio Code: built for the needs of individual developers and the future of the industry Choosing a text editor is a subjective thing. Part of it is about what you’re trying to achieve, and what projects you’re working on, but often it’s not even about that: it’s simply about what feels right. This means that there are always going to be some developers for whom Visual Studio Code doesn’t work – and that’s fine. But unlike many other text editors, Visual Studio Code is so adaptable and flexible to every developers' individual needs, that it’s actually relatively straightforward to find a way to make it work for you. In turn, this means its advantages in terms of cloud native development, and improved collaboration aren’t at the expense of that subjective feeling of ‘yes... this works for me’. And if you’re going to build great software, both things are important. Try Visual Code for yourself. Download it now. Learn how to use Node.js on Azure by downloading Learning Node.js with Azure for free from Microsoft.
Read more
  • 0
  • 0
  • 45597

article-image-understanding-network-port-numbers-tcp-udp-and-icmp-on-an-operating-system
Guest Contributor
16 Apr 2019
16 min read
Save for later

Understanding network port numbers, TCP, UDP, and ICMP on an operating system

Guest Contributor
16 Apr 2019
16 min read
As a student, professional or enthusiast who is interested in the field of computer networking, it is quite important to have a firm understanding and the need for logical (internal) ports on an operating system and protocols. This article is an excerpt taken from the book CompTIA Network+ Certification Guide written by Glen D. Singh and Rishi Latchmepersad. This book will help you understand topics like network architecture, security, network monitoring, troubleshooting and much more. This article provides you with an introduction to understanding network port numbers, TCP, UDP, and ICMP. The term “ports” or “network ports” usually means the physical interfaces or ports on a device, such as a router, switch, server or even a personal computer. However, even though these are the physical ports, there are also logical ports within an operating system or a device. You may ask yourself, how does a physical port exist within a computer, server or a network appliance such as a router or switch? Here, we are going to further breakdown the concepts of these logical ports or what is known as network ports. To get started, we will use a simple analogy to help you understand the fundamentals of logical ports on a system. Let’s imagine you own an organization, at the headquarters location, is a single building with many floors and at the center of the building are the elevators for easy access to the upper floors. Each floor is occupied by a unique department and its respective staff members of the organization. Each day, the employees use the elevators which transport the staff to his/her relevant department and back. Let’s imagine the physical building is a computing system such as a server, there are doors at each relevant department and the employees of the organization are different types of network traffic entering and leaving the system on a daily basis. Now let’s put all the piece together and get everything working in harmony. Each time an employee (network traffic) enters the building (operating system), he/she takes the elevator (Transport Layer) which delivers the employee to their respective doorway (logical port) at their department (service/protocol at the Application Layer). From this analogy, you may have realized each type of network traffic (employee) enters their relevant department using a doorway, this doorway is a logical port existing within the operating system (building) and won’t be visible to any entity outside of the system. Each type of network traffic is sent to a specific logical port for further processing before it’s delivered to the Application Layer. The Internet Assigned Numbers Authority (IANA) is the governing body who manages and regulates Internet Protocol (IP) addresses and Port Numbers assignments.  According to the Service Name and Transport Protocol Port Number Registry of IANA, there are a total of 65,535 ports. Each of which is either Transmission Control Protocol (TCP) or User Datagram Protocol (UDP) port types, there are some ports which are both TCP and UDP types. The ranges of the ports are categorized into three simple categories for easy identification: [box type="shadow" align="" class="" width=""]Get further information on the assignments of port by Internet Assigned Numbers Authority (IANA) on its official website.[/box] Internet Engineering Task Force (IETF) defines the procedures for managing the service names and port numbers by RFC 6335. Now we have a clear understanding of the roles of ports on a system, let’s dive a bit deeper in define some of the well-known ports and their purposes on a network. Network Protocols and their Port numbers A network protocol defines the rules and procedures in which data communication occurs between devices over a network. Without predefined rules or procedures, the messages traversing a network would be without any particular formatting and may not be meaningful to the receipt device. To further discuss the importance of have protocols on a network/system, we will use the following analogy to provide you with a real-world situation in comparison to network protocols. Let’s imagine you work for an organization, ACME Corp and within the company, there are many policies and procedures that govern the handling of day to day transactions and activities within the organization. One of the most important procedure is the emergency evacuation plan. If there’s an emergency with the organization, the procedure documents the rules and guidelines each employee must follow to ensure they are escorted safely out the compound unto the muster point while the health and safety officers conduct their checks before allowing anyone to re-enter the compound. If proper procedures and guidelines didn’t exist within ACME Corp, persons would be attempt exist the compound in a haphazard behavior which may result in further safety issues. With procedures and guidelines, the employees evacuate in a systematic manner. This is the same concept which is applied on the network. There are many different protocols which use a network to communicate with another device. Each protocol has their own uniqueness in which the information is formatted, the rules and procedures it follows while traveling on the network until it is received by the intending receipt and process upwards on the Open Systems Interconnection (OSI) reference model or the Transmission Control Protocol/Internet Protocol (TCP/IP) stack. [box type="shadow" align="" class="" width=""]The ISO Open Systems Interconnection (OSI) is simply a reference model and it not actually implemented on a system, however, network professionals use this model mostly during network and security discussions and troubleshooting concepts. The Transmission Control Protocol/Internet Protocol (TCP/IP) stack is implemented in all network related devices.[/box] Now you have understood the concepts of network protocols, let’s discuss some of the popular protocols and their respective port numbers and their importance on a network. Protocol Types Internet Control Message Protocol (ICMP) On a network, whether on a Local Area Network (LAN) or a Wide Area Network (WAN), host devices will be communicating to exchange data and information between each other and sometimes an error can occur. Let’s imagine you are sending a packet to a server on the internet, while your computer is initializing the connection between itself and the remote server, it provides an error stating unable to connect. As an upcoming networking professional, you may wonder why both devices are unable to successfully establish a connection amongst themselves. Internet Control Message Protocol (ICMP) defined by RFC 792 is typically used to provide error reporting on a network. There are many types of Internet Control Message Protocol (ICMP) messages which provide different actions and give feedback if an error occurs, and also the issue which exists. Internet Control Message Protocol (ICMP) Message Types There are many Internet Control Message Protocol (ICMP) message types however, we’ll be discussing the main ones which will be very useful as a network professional. ICMP Type 0 – Echo Reply The Type 0 message is when a sender device is responding to an ICMP Type 8, Echo request. ICMP Type 3 – Destination Unreachable Type 3 is given then a destination cannot be found or is simply unreachable by the sender. However, ICMP Type 3 gives a bit more details by adding a Code to the message. Code 0 – Network Unreachable Code 1 – Host Unreachable Code 2 – Protocol Unreachable Code 3 – Port Unreachable Therefore combining the ICMP Type 3 message with a unique Code gives you, the network professional a better idea to the error on the network. ICMP Type 5 – Redirect An ICMP Type 5 message occurs when a default gateway device such as a router notifies the sender to send the traffic directly to another gateway which exists on the same network. One reason can the second gateway device or router may have a better route to the destination or a shorter path. ICMP Type 8 – Echo Request The ICMP Type 8 message is used by a sender device to check for basic network connectivity between itself and the intended recipient device. Any device receiving an ICMP Type 8 message, responds with an ICMP Type 0 – Echo Reply. ICMP Type 11 – Time Exceeded Type 11 is given the Time to Live (TTL) expires or reaches zero (0) before reaching the intended recipient device. The last gateway which adjusts the TTL to zero (0) notified the sender using an ICMP Type 11 message as displayed below: The -i parameter adjusts the Time To Live (TTL) value on the ICMP message. C:\>ping 8.8.8.8 -i 4Pinging 8.8.8.8 with 32 bytes of data: Reply from 179.60.213.149: TTL expired in transit. Reply from 179.60.213.66: TTL expired in transit. Reply from 179.60.213.66: TTL expired in transit. Reply from 179.60.213.66: TTL expired in transit. Ping statistics for 8.8.8.8:     Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Without adjusting the Time To Live (TTL) value of the ICMP Type 8 message, the sender received an ICMP Type 0 messages indicating successful transmission between both devices. C:\>ping 8.8.8.8Pinging 8.8.8.8 with 32 bytes of data: Reply from 8.8.8.8: bytes=32 time=52ms TTL=120 Reply from 8.8.8.8: bytes=32 time=52ms TTL=120 Reply from 8.8.8.8: bytes=32 time=52ms TTL=120 Reply from 8.8.8.8: bytes=32 time=52ms TTL=120 Ping statistics for 8.8.8.8:     Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milliseconds: Minimum = 52ms, Maximum = 52ms, Average = 52ms [box type="shadow" align="" class="" width=""]Further information of Internet Control Message Protocol (ICMP) can also be found at: https://tools.ietf.org/html/rfc792.  Further information of all the Internet Control Message Protocol (ICMP) message types can be found at: https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml#icmp-parameters-codes-7.[/box] A simple and easy-to-use utility is Ping. The Ping utility harnesses the functionality of Internet Control Message Protocol (ICMP) and provides meaningful feedback whether communication is successful, unsuccessful, redirected, the destination host or network is unreachable, etc. The Ping utility is integrated into almost every, if not all modern day operating systems, from desktops, servers, and even mobile operating systems. The ping command can be executed in the Windows Command Prompt or the Terminal of Linux-based Operating Systems. When a user initiates the ping command with a destination address, the ping utility would send an ICMP Type 8 message to the intended destination. The syntax for checking basic connectivity is as follows: ping <ip address or hostname> ping 8.8.8.8 ping www.google.com Transmission Control Protocol (TCP) When you send a letter using your local postal service, have you ever wondered if your letter reaches the destination successfully, was your letter prioritized within the processing system of the mail service for delivery or what confirmation would you receive when the letter the is delivered successfully? Imagine in a network, these are the same concerns with devices. If one device sends a datagram to another device, whether one the same Local Area Network (LAN) or a remote network, what reassurance is given for the guarantee of the datagram (message) between sender and the receiver? Transmission Control Protocol (TCP) defined by RFC 793 is a connection-oriented protocol which operates are the Transport Layer of both the Open Systems Interconnection (OSI) reference model and the Transmission Control Protocol/Internet Protocol (TCP/IP) protocol stack. It is designed to provide reliable transportation of the datagrams over a network. It provides reassurance by initializing a 3-way handshake before communicating data between the sender the receiver. Let’s imagine there are two (2) devices who wants to communicate and use TCP to ensure their messages are delivered successfully. Let’s use a simple analogy to further explain the TCP 3-Way Handshake, we have two (2) device, Bob and Alice. Bob wants to exchanges data with Alice but needs to ensure the data being sent are successfully delivered, so Bob decides to use the Transmission Control Protocol (TCP) to guarantee the delivery. Bob initializes the TCP 3-Way Handshake by sending a TCP Synchronization (SYN) packet to Alice indicating he wants to establish a session or connection. Alice, upon receiving the SYN packet, responds to Bob indicating she also wants to establish a session and acknowledges receipt of the SYN packet using a TCP Synchronization and Acknowledgment (SYN/ACK) packet. Bob, upon receiving the TCP SYN packet from Alice, responds with a TCP Acknowledgement (ACK) packet. Now the TCP 3-Way Handshake is established, data can be exchanged between the two (2) devices, each datagram sent across the session between Bob and Alice, an ACK packet will be sent to confirm successful delivery of the message. What if Bob sends a message to Alice, and Bob does not receive an ACK from Alice? In this situation, Bob would retransmit the data again after certain intervals until an ACK packet is sent back to Bob. Another question you may have is, how does Transmission Control Protocol (TCP) terminates a session gracefully? Each device sends a TCP Finish (FIN) packet to each other indicating they would like to terminate the session. Furthermore, if we use a network protocol analyzer tools such as Wireshark, we can see the packet composition of each datagram passing across the network. The following exhibit is a capture using Wireshark during the writing of this book to demonstrate the TCP 3-Way Handshake. [box type="shadow" align="" class="" width=""]Reassemble packet in order[/box] User Datagram Protocol (UDP) User Datagram Protocol (UDP), defined by RFC 768 is a connectionless protocol. This protocol also operates at the Transport Layer of both the Open Systems Interconnection (OSI) reference model and the Transmission Control Protocol/Internet Protocol (TCP/IP) protocol stack. However, unlike Transmission Control Protocol (TCP), the User Datagram Protocol (UDP) does not provide any guarantee or reassurance of the delivery of datagrams across a network. Not all protocols at the Application Layer uses TCP, there are many Layer 7 protocols which uses the User Datagram Protocol (UDP). You may be wondering, why would an upper layer protocol uses UDP instead of TCP? Let do a brief recap of TCP, when devices are using TCP as their preferred Transport Layer protocol, each message sent between the sender and the receiver, an Acknowledge (ACK) packet is returned. This means if a sender such as Bob, sends one hundred (100) packets to Alice over the network, Alice would return one hundred (100) Acknowledgment (ACK) packets to Bob. Let’s imagine a larger network with hundreds, thousands or even the Internet, where everyone would use TCP, the returned traffic, in this case, would the ACK packets, would create a lot of overhead in the network and therefore cause congestion. This is a bit similar to having a roadway and the number of vehicles are increasing, this would cause traffic. Let’s use another analogy, a lot of persons globally uses YouTube for many reasons. Imagine if the video traffic uses TCP instead of UDP, YouTube has millions of users daily who streams content on the site. If each user were to send a TCP ACK packet back to YouTube on that very large scale, the YouTube network and even the Internet would be congested with a lot of TCP ACK packets and would cause the network performance to degrade. Therefore, not all upper layer protocols use TCP because of this issue. The way in which UDP behaves is simply sending datagrams without any reassurance or guarantee delivery of the message. When devices are communicating over a network, the path with each packet may take may be different from the other and therefore may be received in an out-of-order sequence. The User Datagram Protocol (UDP) does not provide any mechanisms for reassembly of the packet unlike the Transmission Control Protocol (TCP) which aids in the reassembly and reordering of the packets when they are received from the sender. [box type="shadow" align="" class="" width=""]Voice and video traffic use UDP as the preferred Transport Layer protocol.[/box] Comparison of TCP and UDP Transmission Control Protocol (TCP) Reliable Uses Acknowledgments to confirm receipt of data Re-sends data of any of the packets are lost during transmission Delivers the data in sequential order and handles reassembly Applications: HTTP, FTP, SMTP, Telnet. User Datagram Protocol (UDP) Very fast in delivery of data Very low overhead on the network Does not require any acknowledgment packets If packets are lost during transmission, it does not resend any lost data Does not send data in order or handles the reassembly Applications: DHCP, DNS, SNMP, TFTP, VoIP, IPTV. [box type="shadow" align="" class="" width=""]There are protocols which uses both TCP and UDP such as DNS and SNMP.[/box] Internet Protocol (IP) Internet Protocol (IP) defined by RFC 791 was created for operations in interconnected systems of packet-switched computer communication networks. Internet Protocol (IP) operates at the Network Layer of the Open Systems Interconnection (OSI) reference model and the Internet Layer of the Transmission Control Protocol/Internet Protocol (TCP/IP) protocol suite. However, Internet Protocol (IP) has three main characteristics: Connectionless – The sender of the message does not know if the recipient is available or not, the protocol sends the messages as is. If the message is successfully delivered to the intended recipient, the sender does not know if the message arrives or not. Since IP behaves a bit like UDP, there is not session create prior to the data communication, which leads to the receiver is not aware of any incoming messages. Uses Best Effort – Best Effort implies that Internet Protocol (IP) is unreliable. Similarly to UDP, Internet Protocol (IP) does not provide any guarantee of the data between a sender and receiver. Furthermore, if any data is lost during the transmission, IP does not have the functionality to facilitate the resending of any lost packets. Media Independent – The benefit of using Internet Protocol (IP) is, it is independent of the type of media being used for transporting the data between the sender and the receiver. At times, there are many different types of media between the sender and the receiver, such as copper cables, radio frequency, fiber optic, etc. Internet Protocol (IP) datagrams can be transported over any media type, the Data Link is responsible for formatting the Frame for each type of media as it leaves a device. Thus, in this article, we learned about the network port numbers and also about the different protocol types in detail. If you’ve enjoyed reading this article, and want to get a better understanding of the Network+ Certification read our book, CompTIA Network+ Certification Guide. Bo Weaver on Cloud security, skills gap, and software development in 2019 What matters on an engineering resume? Hacker Rank report says skills, not certifications Wolf Halton on what’s changed in tech and where we are headed
Read more
  • 0
  • 0
  • 101020

article-image-how-to-manipulate-observables-using-operators-in-rxjs-tutorial
Sugandha Lahoti
13 Apr 2019
7 min read
Save for later

How to manipulate observables using operators in RxJS [Tutorial]

Sugandha Lahoti
13 Apr 2019
7 min read
In this section, we are going to learn how to use some functions known as operators, which allow us to manipulate observables in RxJS in different ways. This post is extracted from the book Hands-On Functional Programming with TypeScript by Remo H. Jansen. In this book, you will delve into the principles, patterns, and best practices of functional and reactive programming. Pipe In RxJS, observables have a method named pipe, which is very similar to the pipe operator in functional programming. When we pipe two functions, we generate a new function that passes the return of the first function as arguments to the second function in the pipe. The idea is very similar in reactive programming. When we pipe an observable through an operator, we generate a new observable. The new observable passes each of the items in the original observable to an operator that transforms them into the items in the new sequence. We are not going to include a code example here, because we are going to use the pipe method multiple times during the remaining part of this post. Max The max operator function can be used to find the biggest value in an observable. We must apply the max operator using the pipe method: import { from } from "rxjs"; import { max } from "rxjs/operators"; const observable = from<number>([2, 30, 22, 5, 60, 1]); observable.pipe(max()); const subscription = observable.subscribe( (value) => console.log(value) ); subscription.unsubscribe(); The following marble diagram showcases the initial sequence and the result sequence after applying the max operator: The result sequence contains only one value (the biggest value in the original sequence). Every The every operator function can be used to test whether all the values in an observable adhere to a given requirement: import { from } from "rxjs"; import { every } from "rxjs/operators"; const observable = from<number>([1,2, 3, 4, 5]); observable.pipe(every(x => x < 10)); const subscription = observable.subscribe( (value) => console.log(value) ); subscription.unsubscribe(); The preceding code snippet uses every operator to test that all the values in an observable are lower than ten. The following marble diagram showcases the initial sequence and the result sequence after applying every operator: The result sequence contains only one value (true or false). Find The find operator function can be used to find the first value in an observable that adheres to a given constraint: import { from } from "rxjs"; import { find } from "rxjs/operators"; const observable = from<number>([2, 30, 22, 5, 60, 1]); observable.pipe(find(x => x > 10)); const subscription = observable.subscribe( (value) => console.log(value) ); subscription.unsubscribe(); The preceding code snippet uses the find operator to find the first value in an observable greater than ten. The following marble diagram showcases the initial sequence and the result sequence after applying the find operator: The result sequence contains only one value (the first value in the stream that matches the given constraint). Filter The filter operator function can be used to find the values in an observable that adhere to a given constraint: import { from } from "rxjs"; import { filter } from "rxjs/operators"; const observable = from<number>([2, 30, 22, 5, 60, 1]); observable.pipe(filter(x => x > 10)); const subscription = observable.subscribe( (value) => console.log(value) ); subscription.unsubscribe(); The preceding code snippet uses the filter operator to find the values in an observable greater than ten. The following marble diagram showcases the initial sequence and the result sequence after applying the filter operator: The result sequence contains only some values (the values in the stream that match the given constraint). Map The map operator function can be used to transform the values in an observable into derived values: import { from } from "rxjs"; import { map } from "rxjs/operators"; const observable = from<number>([1, 2, 3]); observable.pipe(map(x => 10 * x)); const subscription = observable.subscribe( (value) => console.log(value) ); subscription.unsubscribe(); The preceding code snippet uses the map operator to transform the values in an observable into new values (the original value multiplied by ten). The following marble diagram showcases the initial sequence and the result sequence after applying the map operator: The result sequence contains a new mapped value for each value in the original sequence. Reduce The reduce operator function can be used to transform all the values in an observable into one single value: import { from } from "rxjs"; import { reduce } from "rxjs/operators"; const observable = from<number>([1, 2, 3, 3, 4, 5]); observable.pipe(reduce((x, y) => x + y)); const subscription = observable.subscribe( (value) => console.log(value) ); subscription.unsubscribe(); The preceding code snippet uses the reduce operator to transform the values in an observable into a new single value (the total of all the values). The function that transforms multiple values into one single value is known as an accumulator. The following marble diagram showcases the initial sequence and the result sequence after applying the reduce operator: The result sequence contains only one value (the result of the accumulator). Throttle The throttle operator function can be used to reduce the number of values that are added to an observable: import { fromEvent, interval } from "rxjs"; import { throttle, mapTo, scan } from "rxjs/operators"; const observable = fromEvent(document, "click") .pipe(mapTo(1)) .pipe(throttle(x => interval(100))) .pipe(scan((acc, one) => acc + one, 0)); const subscription = observable.subscribe( (value) => console.log(value) ); subscription.unsubscribe(); The preceding code snippet creates an observable for click events. Every click will add an item to the sequence. The example also uses the pipe method and the mapTo function to map all the click events to the numeric value 1. It is then when we use the throttle operator to reduce the number of values that are added to the sequence. If two or more click events take place within a time interval lower than the one declared by the interval, only the first value will be added to the sequence. The following marble diagram showcases the initial sequence and the result sequence after applying the reduce operator: The result sequence only contains some values because the values that take place too close in time are ignored. Merge The merge operator function can be used to merge the values of two observables into value pairs: import { from } from "rxjs"; import { merge } from "rxjs/operators"; const observableA = from<number>([20, 40, 60, 80, 100]); const observableB = from<number>([1, 1]); const observableC = observableA.pipe(merge<number, number>(observableB)); const subscription = observableC.subscribe( (value) => console.log(value) ); subscription.unsubscribe(); The preceding code snippet uses the merge operator to combine the values of two observables into a new observable. The values are ordered chronologically. The following marble diagram showcases the initial sequences and the result sequence after applying the merge operator: The result sequence contains the values of both observables ordered in the same sequence as they took place in time. Zip The zip operator function can be used to merge the values of two observables into value pairs: import { from } from "rxjs"; import { zip } from "rxjs/operators"; const observableA = from<number>([1, 2, 3, 3, 4, 5]); const observableB = from<string>(["A", "B", "C", "D"]); const observableC = observableA.pipe(zip<number, string>(observableB)); const subscription = observableC.subscribe( (value) => console.log(value) ); subscription.unsubscribe(); The preceding code snippet uses the zip operator to combine the values of two observables into a new observable. The values in the new observable are value pairs that contain a value from the first observable and a value from the second observable and are grouped by their index in the sequence. The following marble diagram showcases the initial sequences and the result sequence after applying the zip operator: The result sequence contains the values of both observables merged into single value pairs. In this post, we learned different types of operators, which allow us to manipulate observables in RxJS in different ways.  To further understand the pros, cons, and core principles of functional programming in TypeScript, read our book Hands-On Functional Programming with TypeScript. What makes functional programming a viable choice for artificial intelligence projects? Why functional programming in Python matters: Interview with best selling author, Steven Lott Introducing Coconut for making functional programming in Python simpler
Read more
  • 0
  • 0
  • 17962
article-image-wikileaks-founder-julian-assange-arrested-for-conspiracy-to-commit-computer-intrusion
Savia Lobo
12 Apr 2019
6 min read
Save for later

Wikileaks founder, Julian Assange, arrested for “conspiracy to commit computer intrusion”

Savia Lobo
12 Apr 2019
6 min read
Julian Assange, the Wikileaks founder, was arrested yesterday in London, in accordance with the U.S./UK Extradition Treaty. He was charged with assisting Chelsea Manning, a former intelligence analyst in the U.S. Army, to crack a password on a classified U.S. government computer. The indictment states that in March 2010, Assange assisted Manning by cracking password stored on U.S. Department of Defense computers connected to the Secret Internet Protocol Network (SIPRNet), a U.S. government network used for classified documents and communications. Being an intelligence analyst, Manning had access to certain computers and used these to download classified records to transmit to WikiLeaks. “Cracking the password would have allowed Manning to log on to the computers under a username that did not belong to her. Such a deceptive measure would have made it more difficult for investigators to determine the source of the illegal disclosures”, the indictment report states. “Manning confessed to leaking more than 725,000 classified documents to WikiLeaks following her deployment to Iraq in 2009—including battlefield reports and five Guantanamo Bay detainee profiles”, Gizmodo reports. In 2013, Manning was convicted of leaking the classified U.S. government documents to WikiLeaks. She was jailed in early March this year as a recalcitrant witness after she refused to answer the grand jury’s questions. According to court filings, after Manning’s arrest, she was held in solitary confinement in a Virginia jail for nearly a month. Following Assange’s arrest, a Swedish software developer and digital privacy activist, Ola Bini, who is allegedly close to Wikileaks founder Julian Assange has also been detained. “The official said they are looking into whether he was part of a possible effort by Assange and Wikileaks to blackmail Ecuador’s President, Lenin Moreno”, the Washington Post reports. Bini was detained at Quito’s airport as he was preparing to board a flight for Japan. Martin Fowler, a British software developer and renowned author and speaker, tweeted on Bini’s arrest. He said that Bini is a strong advocate and developer supporting privacy, and has not been able to speak to any lawyers. https://twitter.com/martinfowler/status/1116520916383621121 Following Assange’s arrest, Hillary Clinton, who was the nominee for the 2016 Presidential elections, said, “The bottom line is that he has to answer for what he has done”. “WikiLeaks’ publication of Democratic emails stolen by Russian intelligence officers during the 2016 election season hurt Clinton’s presidential campaign”, the Washington Post reports. Assange, who is an Australian citizen, was dragged out of Ecuador’s embassy in London after his seven-year asylum was revoked. He was granted Asylum by former Ecuadorian President Rafael Correa in 2012 for publishing sensitive information about U.S. national security interests. Australian PM, Scott Morrison told Australian Broadcasting Corp. the charge is a “matter for the United States” and has nothing to do with Australia. He was granted asylum just after “he was released on bail while facing extradition to Sweden on sexual assault allegations. The accusations have since been dropped but he was still wanted for jumping bail”, the Washington Post states. A Swedish woman alleged that she was raped by Julian Assange during a visit to Stockholm in 2010. Post Assange’s arrest on Thursday, Elisabeth Massi Fritz, the lawyer for the unnamed woman, said in a text message sent to The Associated Press that “we are going to do everything” to have the Swedish case reopened “so Assange can be extradited to Sweden and prosecuted for rape.” She further added, “no rape victim should have to wait nine years to see justice be served.” “In 2017, Sweden’s top prosecutor dropped a long-running inquiry into a rape claim against Assange, saying there was no way to have Assange detained or charged within a foreseeable future because of his protected status inside the embassy”, the Washington Post reports. In a tweet, Wikileaks posted a photo of Assange with the words: “This man is a son, a father, a brother. He has won dozens of journalism awards. He’s been nominated for the Nobel Peace Prize every year since 2010. Powerful actors, including CIA, are engaged in a sophisticated effort to dehumanize, delegitimize and imprison him. #ProtectJulian.” https://twitter.com/wikileaks/status/1116283186860953600 Duncan Ross, a data philanthropist, tweeted, “Random thoughts on Assange: 1) journalists don’t have to be nice people but 2) being a journalist (if he is) doesn’t put you above the law.” https://twitter.com/duncan3ross/status/1116610139023237121 Edward Snowden, a former security contractor who leaked classified information about U.S. surveillance programs, says the arrest of WikiLeaks founder Julian Assange is a blow to media freedom. “Assange’s critics may cheer, but this is a dark moment for press freedom”, he tweets. According to the Washington Post, in an interview with The Associated Press, Rafael Correa, Ecuador’s former president, was harshly critical of his successor’s decision to expel the Wikileaks founder from Ecuador’s embassy in London. He said that “although Julian Assange denounced war crimes, he’s only the person supplying the information.” Correa said “It’s the New York Times, the Guardian and El Pais publishing it. Why aren’t those journalists and media owners thrown in jail?” Yanis Varoufakis, Economics professor and former Greek finance minister, tweeted, “It was never about Sweden, Putin, Trump or Hillary. Assange was persecuted for exposing war crimes. Will those duped so far now stand with us in opposing his disappearance after a fake trial where his lawyers will not even now the charges?” https://twitter.com/yanisvaroufakis/status/1116308671645061120 The Democracy in Europe Movement 2025 (@DiEM_25) tweeted that Assange’s arrest is “a chilling demonstration of the current disregard for human rights and freedom of speech by establishment powers and the rising far-right.” The movement has also put a petition against Assange’s extradition. https://twitter.com/DiEM_25/status/1116379013461815296 Google employees filed petition to remove anti-trans, anti-LGBTQ and anti-immigrant Kay Coles James from the AI council A security researcher reveals his discovery on 800+ Million leaked Emails available online Leaked memo reveals that Facebook has threatened to pull investment projects from Canada and Europe if their data demands are not met
Read more
  • 0
  • 0
  • 14137

article-image-postgresql-security-a-quick-look-at-authentication-best-practices-tutorial
Natasha Mathur
12 Apr 2019
12 min read
Save for later

PostgreSQL security: a quick look at authentication best practices [Tutorial]

Natasha Mathur
12 Apr 2019
12 min read
Data protection and security are essential for the continuity of business. Data protection is not recommended, but it is required by the legal system. Sensitive data, such as user information, email addresses, geographical addresses, and payment information, should be protected against any data breach. There are several other topics related to data security, such as data privacy, retention, and loss prevention. In this article, we will look at authentication best practices in PostgreSQL including PostgreSQL host-based authentication, and proxy authentication strategies.  There are several levels of data protection, often defined in the data protection policy and by the country's legal system. A data protection policy often defines data dissemination to other parties, users authorized to access the data, and so on. Data should be protected on different levels, including transferring and encrypting data on storage devices. Data security is a huge topic and often there are data security managers dedicated only to these tasks. This article is an excerpt taken from the book 'Learning PostgreSQL 11 - Third Edition' by Andrey Volkov,  and Salahadin Juba. The book explores the latest features in PostgreSQL 11 and will get you up and running with building efficient PostgreSQL database solutions from scratch.  Authentication in PostgreSQL Authentication answers the question: Who is the user? PostgreSQL supports several authentication methods, including the following: Trust: Anyone who can connect to the server is authorized to access the database/databases as specified in the pg_hba.conf configuration file. Often used to allow connection using Unix domain socket on a single user machine to access the database. This method can also be used with TCP/IP, but it is rare to allow connection from any IP address other than the localhost.  Ident: This works by getting the client's operating system user name from an ident server and then using it to access the database server. This method is recommended for closed networks where client machines are subject to tight controls by system administrators. Peer: This works in a similar manner to ident, but the client's operating system username is obtained from the kernel. GSSAPI: GSSAPI is an industry standard defined in RFC 2743. It provides automatic authentication (single sign-on). Lightweight Directory Access Protocol (LDAP): The LDAP server is used only to validate the username/password pairs. Password authentication: There are three methods as follows: SCRAM-SHA-256: The strongest authentication method, introduced in PostgreSQL 10. This method prevents password sniffing on untrusted connections. The default password authentication method is MD5 to use this feature, the configuration parameter   password_encryption    should be changed to  scram-sha-256 MD5: MD5 has known limitations such as pre-computed lookup tables to crack password hashes.  Also, MD5 has only 4 billion unique hashes.  Finally, MD5 computation is very fast, thus brute force password guessing does not require a lot of CPU resources.  For new applications, it is only recommended using scram-sha-256. Also, PostgreSQL provides the means to migrate from scram-sha-256. Password: This is not recommended to be used since passwords are sent to the server in a clear text format.  There are other authentication methods not covered; the full list of supported authentication methods can be found on the PostgreSQL website. To understand authentication, you need to have the following information: Authentication is controlled via a pg_hba.conf file, where hba stands for host-based authentication. It is good to know the default initial authentication settings shipped with PostgreSQL distribution. The pg_hba.conf file is often located in the data directory, but it can also be specified in the postgresql.conf configuration file. When changing the authentication, you need to send a SIGHUP signal, and this is done via several methods based on the PostgreSQL platform. Note that the user who sends the signal should be a superuser or the postgres, or a root system user on the Linux distribution; again, this depends on the platform. Here is an example of several ways to reload the PostgreSQL configuration: psql -U postgres -c "SELECT pg_reload_conf();"sudo service postgresql reloadsudo /etc/init.d/postgresql reloadsudo Kill -HUP <postgres process id>sudo systemctl reload postgresql-11.service The order of the pg_hba.conf records or entries is important. The session connection is compared with the pg_hba.conf records one by one until it is rejected or the end of the configuration file is reached. Finally, it is important to check the PostgreSQL log files to determine whether there are errors after configuration reload. PostgreSQL pg_hba.conf As in postgresql.conf, the pg_hba.conf file is composed of a set of records, lines can be commented using the hash sign, and spaces are ignored. The structure of the pg_hba.conf file record is as follows: host_type database user [IP-address| address] [IP-mask] auth-method [auth-options] The host_type part of this query can be the following: Local: This is used in Linux systems to allow users to access PostgreSQL using a Unix domain socket connection. Host: This is to allow connections from other hosts, either based on the address or IP address, using TCP/IP with and without SSL encryption. Hostssl: This is similar to the host, but the connection should be encrypted using SSL. Hostnossl: This is also similar to host, but the connection should not be encrypted. The database part of the query is the name of the database that the user would like to connect to. For flexibility, you could also use a comma-separated list to specify several databases, or you could use all to indicate that the user can access all the databases in the database cluster. Also, the same user and same role values can be used to indicate that the database name is the same as the username, or the user is a member of a role with the same name as the database. The user part of the query specifies the database user's name; again, the all value matches all users. The IP address, address, and IP subnet mask are used to identify the host from where the user tries to connect. The IP address can be specified using a Classless Inter-Domain Routing (CIDR) or dot-decimal notation. Finally, the password authentication methods can be trusted, MD5, reject, and so on. The following are some typical examples of configuring a PostgreSQL authentication: Example 1: Any user on the PostgreSQL cluster can access any database using the Unix domain socket, as shown in the following database table: #TYPE DATABASE USER ADDRESS METHODLocal all all trust Example 2: Any user on the PostgreSQL cluster can access any database using the local loop back IP address, as shown in the following database table: #TYPE DATABASE USER ADDRESS METHODHost all all 127.0.0.1/32 trusthost all all ::1/128 trust Example 3: All connections that come from the IP address 192.168.0.53 are rejected, and the connections that come from the range 192.168.0.1/24 are accepted, as shown in the following database table: #TYPE DATABASE USER ADDRESS METHODHost all all 192.168.0.53/32 rejectHost all all 192.168.0.1/24 trust PostgreSQL provides a very convenient way to view the rules defined in the pg_hba.conf file by providing a view called pg_hba_file_rules as follows: postgres=# SELECT row_to_json(pg_hba_file_rules, true) FROM pg_hba_file_rules limit 1; row_to_json ------------------------- {"line_number":84, + "type":"local", + "database":["all"], + "user_name":["all"], + "address":null, + "netmask":null, + "auth_method":"trust",+ "options":null, + "error":null}(1 row) Listen addresses The listen_addresses option is defined in postgresql.conf. The PostgreSQL listen_addresses connection setting is used to identify the list of IP addresses that the server should listen to from client applications. The listen_addresses are comma-separated lists of hostnames or IP addresses. Changing this value requires a server restart. In addition, the following should be noted: The default value is localhost which restricts direct connections to PostgreSQL cluster from network.. Giving an empty list means that the server should accept only a Unix socket connection The value * indicates all It is a common mistake for developers new to PostgreSQL to forget to change the listen_address. If a developer forgets to change it and tries to connect to PostgreSQL using TCP/IP from the network, the following error will be raised:     Connection refused   Is the server running on host <host_ip> and accepting  TCP/IP connections on port 5432? Authentication best practices Authentication best practices depend on the whole infrastructure set up, the application's nature, the user's characteristics, data sensitivity, and so on. For example, the following setup is common for start-up companies: the database application, including the database server, is hosted on the same machine and only used from one physical location by intracompany users. Often, database servers are isolated from the world using firewalls; in this case, you can use the SCRAM-SHA-256 authentication method and limit the IP addresses so that the database server accepts connections within a certain range or set. Note that it is important not to use a superuser or database owner account to connect to the database because if this account was hacked, the whole database cluster would be exposed. If the application server—business logic—and database server are not on the same machine, you can use a strong authentication method, such as LDAP and Kerberos. However, for small applications where the database server and application are on the same machine, the SCRAM-SHA-256 authentication method and limiting the listen to address to the localhost might be sufficient. To authenticate an application, it is recommended to use only one user and try to reduce the maximum number of allowed connections using a connection pooling software to better tune the PostgreSQL resources. Another level of security might be needed in the application of business logic to distinguish between different login users. For real-world users, LDAP or Kerberos authentication is more desirable. Furthermore, if the database server is accessed from the outer world, it is useful to encrypt sessions using SSL certificates to avoid packet sniffing. You should also remember to secure database servers that trust all localhost connections, as anyone who accesses the localhost can access the database server. Role system and proxy authentication Often, when designing an application, a login role is used to configure database connections and connection tools. Another level of security needs to be implemented to ensure that the user who uses the application is authorized to perform a certain task. This logic is often implemented in application business logic. The database's role system can also be used to partially implement this logic by delegating the authentication to another role after the connection is established or reused, using the SET SESSION AUTHORIZATION statement or SET ROLE command in a transaction block, as follows: postgres=# SELECT session_user, current_user; session_user | current_user --------------+-------------- postgres | postgres(1 row)postgres=# SET SESSION AUTHORIZATION test_user;SETpostgres=> SELECT session_user, current_user; session_user | current_user --------------+-------------- test_user | test_user(1 row) The SET ROLE requires a role membership, while SET SESSION AUTHORIZATION requires superuser privileges. Allowing an application to connect as a superuser is dangerous because the SET SESSION AUTHORIZATION and SET ROLE commands can be reset using the RESET ROLE and RESET SESSION commands, respectively, thereby allowing the application to gain superuser privileges. To understand how the PostgreSQL role system can be used to implement authentication and authorization, we will use the role system and the car portal application. In the car portal application, several groups of users can be classified as web_app_user, public_user, registered_user, seller_user, and admin_user. The web_app_user is used to configure business logic connection tools; the public_user, registered_user, and seller_user are used to distinguish users. The public_user group can access only public information, such as advertisements, but cannot add ratings as registered_user nor create advertisements, since seller_user. admin_user is a super role to manage all of the application's content, such as filtering out spams and deleting the users that do not adhere to the website's policies. When the car web portal application connects to the database, the web_app_user user is used. After this, car_portal invokes the SET ROLE command based on the user class. This authentication method is known as proxy authentication. The following examples demonstrate how a role system can be used to implement proxy authentication. The first step is to create roles and assign role memberships and privileges, as follows: CREATE ROLE web_app_user LOGIN NOINHERIT;CREATE ROLE public_user NOLOGIN;GRANT SELECT ON car_portal_app.advertisement_picture, car_portal_app.advertisement_rating , car_portal_app.advertisement TO public_user;GRANT public_user TO web_app_user;GRANT USAGE ON SCHEMA car_portal_app TO web_app_user, public_user; The NOINHERIT option for the web_app_user does not allow the user to inherit the permissions of role membership; however, web_app_user can change the role to a public user, as in the following example: $ psql car_portal -U web_app_usercar_portal=> SELECT * FROM car_portal_app.advertisement;ERROR: permission denied for relation advertisementcar_portal=> SET ROLE public_user;SETcar_portal=> SELECT * FROM car_portal_app.advertisement; advertisement_id | advertisement_date | car_id | seller_account_id ------------------+--------------------+--------+-------------------(0 rows)car_portal=> SELECT session_user, current_user; session_user | current_user --------------+-------------- web_app_user | public_user(1 row) In this article, we looked at several authentication methods in PostgreSQL such as password and trust.  Finally, we looked at the role system and proxy authentication. If you enjoyed reading the article and want to learn more, be sure to check out the book ''Learning PostgreSQL 11 - Third Edition'.  How to handle backup and recovery with PostgreSQL 11 [Tutorial] Handling backup and recovery in PostgreSQL 10 [Tutorial] Understanding SQL Server recovery models to effectively backup and restore your database
Read more
  • 0
  • 0
  • 57058
Modal Close icon
Modal Close icon