Advice from someone who does not know everything.

Category: Techie Stuff (Page 1 of 2)

Artaygo – Artificial Intelligence Generated Artwork

I recently spoke with the owners of Artaygo. The company offers one of a kind, canvas art pieces that are generated using artificial intelligence. It’s a very unique product offering for customers who would like original pieces at more affordable prices. There are multiple themes available and it continues to grow in selection.

The following is a question and answer style interview about the company and how the artwork process works.

Q: Why the name “Artaygo”?  Where did it come from?

The choice of the name Artaygo is a mix of branding potential, ease of pronunciation, availability, and linkage to the content.  Artaygo is primarily a play on words combining “Art” and “AI” in a way that is easy to pronounce. We started with a brainstorming session writing down a few dozen words that might be relevant – words like AI, art, artificial, machine, gallery, generative and so on, and from there played around with variations of them. 

There are quite a few sites that help with generating business names which were helpful at getting ideas for prefixes and suffixes.  But at the end of the day it came down to spending a weekend with Excel open, and generating all kinds of prefixed and suffixed versions and picking favorites.

“The Darkseed” – AI Generated Artwork

Q: What is your interest in art historically?

Although our personal background is pretty focused on finance & capital markets, we’ve done a lot of work in the past in photoshop, graphic design work and just experimenting with other visual arts packages, including 3DSMax, Maya and Blender.

As a homeowner it also became more topical to think about home decorating, framed canvas and other wall art. We have a mix of art types at home, and I’ve often wondered if there was an interesting middle ground between basic printed wall art and more expensive original oil paintings.

Q: When did you get the idea to create this site and what were your motivations?

Our introduction to AI / Deep Learning / Machine learning was in late 2017 and we became very familiar with a lot of the different algorithms that existed back then. Initially it was more out of general curiosity as a bit of a sci-fi nerd. The general concept of AI seemed so far-out versus anything we had seen previously.  Just the idea that you can create a generalized architecture in which a computer can ‘think’ for itself and solve a variety of problems without much human input is completely amazing. And having watched this space now for several years, it’s incredible to see the innovation that’s been happening – much of it just trial and error because there isn’t a lot of academic theory behind it yet. 

In terms of motivations, we really like art, graphic design, and AI personally, plus with a business background, what better way to put that together, but by putting computers to work at creating art? I also think it’s a great service that benefits people, because while everyone aspires to have their own original hand-painted artwork, realistically you’re not going to furnish your first home with multiples pieces of art at $2,000-$10,000+ each.  So for folks getting into their first home – there wasn’t really a way to decorate a house with something completely original, one-of-a-kind, with high quality materials and at a reasonable price. So it’s great to be a part of offering a solution to that problem.

Q: I would love some details on how this works if it doesn’t give away any secrets. What is the algorithm behind the art generation?

The core principal is something called a generative adversarial network (GAN). So you actually create two neural networks which fight against each other. Initially, the generator network really just makes colorful noise – just random guesses for every pixel in an image, while the discriminator network looks at the fake noisy pictures, and looks at real pictures, and assigns a probability of the images being real or fake. Initially, neither the generator nor the discriminator has any idea what it’s doing and is pretty inaccurate. Then the results are scored, and the generator is rewarded for fooling the discriminator, and the discriminator is rewarded for correctly determining if an image is real or fake.  So this process then repeats and the act of rewarding the networks causes them to improve over time.

Q: If it is being trained, how does it find art to train itself with?

We need to provide the GAN with copies of what it’s trying to emulate – and the broader the subject matter we provide, the broader range of outputs we produce.  So if you want the GAN to produce portraits of people – it won’t learn to do that if you provide it pictures of landscapes.  On the other hand, if you provide it pictures of all art ever produced, the model will suffer from numerous challenges including taking a very long time to train, having a tendency to ‘cheat’ by just drawing one type of art successfully and ignoring other types, among other issues.  So we have to act as a teacher who guides the student to learn a reasonably curated set of examples. 

However once you have a trained artist, you can ‘transfer’ its learnings and begin learning a different subject matter more quickly.  So if you had taught an AI artist landscape painting, you can take a copy of that artist and tell it to train on portraits, and it would adapt to be a portrait painter much more quickly than if it started from scratch.  

“Summertime Sadness” – AI Generated Artwork

Q: What computer hardware is being utilized to create the artwork?  Is it local or cloud hosted?  

All machine learning these days is being done on graphics cards, primarily made by NVIDIA, because they’re really effective at the type of math required for training neural nets. Your typical Intel or AMD CPU is extremely fast at doing single tasks (or 8-16 tasks if we’re talking typical CPUs these days with multiple cores).  Compare that to graphics cards which are designed exclusively to do a smaller amount of math across millions of pixels in unison, and repeated at least 60 times per second. That graphic card structure is much more aligned to how neural networks behave, with millions of connections that need to be updated simultaneously during the training process. So we’ve been fortunate enough to get a very good NVIDIA card and run a lot of work locally, but it’s also required a lot of effort in managing memory and using a few hacks to live within memory and time constraints. 

We have been thinking about migrating to Amazon AWS for a couple reasons. First, running it locally means it fully occupies local machine – and especially as we approach the summer – it starts to heat up a room pretty fast! Also by going on AWS it would let us get quicker turnaround time on experimentation and simply not need to think as much about the trade-offs of complexity and training speed as much.

Q: How long does it take to train and how many pieces of art will it train with?  This probably translates into an average time per piece of training art?

Training and art generation are similar to what you might expect from a human artist, just accelerated. You might think about a human artist training for years to become a master, at which point each work of art is quite good, and then takes an order of magnitude less time to paint each new masterpiece than the cumulative training time up to that point. Similarly AI artists have a large up-front training time that can take days or weeks, at which point the artist is quite good and can produce new art relatively quickly. In terms of training materials, you can theoretically achieve ‘interesting’ results when you train on a very small dataset of dozens of images – sometimes an output with unusual visual artifacts or ‘stuttering’ can make for an appealing effect. But generally you want at least a dataset in the ‘low thousands’ of images and at the extreme upper end, maybe 50 to 100 thousand images. But that upper limit keeps coming down as new techniques and architectures develop.

One of the recent discoveries by researchers is that if you use aggressive augmentation of the images, it works almost as good as having extra original images.  So for example you can flip an image horizontally, zoom the image, slightly rotate or tilt the image, or adjust its color saturation slightly – and doing these small adjustments greatly improves the ability of GANs to produce a variety of output without needing an abundance of input materials to learn from.  

Q: What were some of the biggest hurdles in developing it? 

There are tons of hurdles that we didn’t expect! Whether coding, getting good data, seeing unexpected results, and even getting online with print suppliers. One issue that’s a bit more tech-oriented is simply the trade-off between resolution and compute time. So running a basic GAN at 256×256 pixels for 12 hours might produce great results. But to generate that at 512×512 – twice the width and height actually takes 4x longer to train – 48 hours.  Then going to higher resolutions takes even more time – so to get the quality of that original 256×256 image at 2048×2048 would take 768 hours (about 32 days)  – or so you would think.

You can imagine the frustration when you think everything is going to work and 8 days into training you check the results and every image looks identical – a phenomenon called GAN collapse. That happens when the networks get ‘stuck’ and only generate a single type of content. Working around these kinds of issues where you spend a lot of time waiting before knowing if you’ll have success or not – that’s probably the hardest hurdle.     

Q: Do you have any noteworthy improvements you want to make to the algorithm? 

There isn’t anything architecture wise that is mission critical, so any improvements are very ‘on the margins’ and a bit academic. But SOTA (State of the Art) is always changing, so we could completely overhaul the architecture if there was a compelling enough reason. There are many public GAN codebases which occasionally implement new techniques, so we kind of watch to see what is new & interesting there to see if we can implement similar concepts. Most GANs today rely on an image recognition architecture called convolution, which allows the AI to detect primitive shapes and stack them into more complicated features. So what gets us the most excited is stepping outside of convolution and some alternate architectures called Transformers (also known as Attention) and Diffusion Models, but they aren’t yet surpassing convolutional approaches just yet. So the old adage holds true, if it ain’t broke, don’t fix it!  

Q: How long did it take you to develop the app and output your first “usable” piece of artwork?

It took a few months to get things up and running where content looked decent. So much code and research papers are open sourced, so you can get basic items going quickly, but implementing some of the newer features like style mapping and augmentation takes more work. But the very first piece of content ended up not looking as great as we hoped when printed to canvas, so we went back to the drawing board and found solutions to get final output that looked good. I still have a copy of that early framed canvas hanging in my office as a reminder of where things started.

Q: Of the artwork generated, does a human look through for ones that look interesting? What percentage are rejected? What are the reasons for rejection?  General appearance does not look good, doesn’t fit the theme, too similar to other art pieces, etc?

Yes, we look through and are rejecting anything that looks subjectively ‘bad’.  It’s maybe 10% or so that get rejected.  So for example in the training data you might have a black and white image, which we thought was useful for capturing the foliage of a different tree style. But some small percentage of output images may appear partially black & white, and just don’t align to the collection very well.  Sometimes the unusual artifacts that get generated are actually really cool (see a blog post about the hidden secrets of AI Art here) but sometimes they’re more obviously ‘mistakes’.  The longer we train the models, the lower the rejection rate. But it’s sometimes easier and more enjoyable to just take a look at the artwork.  

Q: Does a person create the titles for each art piece?

It’s a mix – initially we created most of the titles by human means, and pulled in the expert assistance of my daughter! In one of our recent collections, called the Alleys of Old Europe, we made a simple GAN to generate names of European cities and used that to give every image a name belonging to a totally fictional city. So they have names like Midleshannon, Prejek, Afragliano for example, which to the best of our knowledge are not actual places, but sound like they’d fit right into someplace in England, Croatia and Italy. Certainly as we move forward, we plan to implement other systems that name the works as well.

“Korzë” – AI Generated Artwork

Q: Could a user ever “influence” the algorithm to generate more custom art?

In theory yes, and there are a couple of ways to achieve that. One approach we’ve seen in other GAN repositories is to label the training data, so while the GAN is trained on a large body of work, you have more control in terms of generating content which is true to the label.  So you could train it on a collection of cat, dog and horse images, but then only ask to have horses generated.  Another approach is using a technique called neural style transfer, where you can transfer the visual style of one image onto another – so if you can project the style of Van Gogh’s starry night onto a picture of your backyard. There are a few other techniques that can be adapted from of other GANs as well.  

Q: You say it is one-of-a-kind, how do you guarantee that?  The art is taken down and not available for purchase once someone does buy it?

That’s right – although the buyer has full control over what size they want the art produced at, once a single print is purchased, it is no longer available for sale again at any size. As for guaranteeing uniqueness – Depending on the model we’re using, the initial ‘seed’ of an image is based on a 256 to 1,024 digit random code, so the odds of seeing an identical work are astronomically small (i.e. you might say there are 10^256 to 10^1024 possible inputs compared to 10^80 atoms in the universe). Furthermore, as we train and update the models over time, the same random digit sequence won’t produce quite the same output either, even if you re-used the same seed.

Q: Does the purchaser also get the digital file?

At this moment, no, but we might consider expanding that offering. There is also a lot of excitement about NFTs – non-fungible-tokens, where buyers receive a digital copy of the art along with blockchain certified proof of ownership. We’re not sure if our target market tilts that direction – physical ownership has its perks! But it’s certainly something we’d be open to explore.

Q: Do you retain the original file as well in case a reprint is needed?

We don’t. We do retain the files during the refund period in the event a customer doesn’t want to keep their piece, and also to ensure that if the art is damaged during delivery we can offer a replacement.  However after the return window closes, we delete the high-res files and just keep the low resolution versions for marketing purposes, and to have a visual record of what’s been sold.  While it might be nice to have a ‘backup’ with us, we felt that customers having confidence in the uniqueness of their product was preferred.I see themes on the site. 

Q: What other themes can we expect upcoming? 

Within the broader impressionism school of art, we’re looking at still life, portraits, and potentially doing more narrow themes – impressionist “fields” versus impressionist “mountains” or “cityscapes”. We also have quite a few ideas in photorealism, but those require a bit more field work to gather original private content to implement. I think there is a lot of potential in combining styles and content that have never co-existed – just off the top of my head, maybe doing a series of sportscars with Japanese sumi-e style brush strokes.

Q: Any plans on other product offerings?  Whether it is different sizings or other mediums. 

In terms of sizing we can technically offer any size – so while we have a pretty good range on the website, in theory a customer can reach out and have something different produced. Moving to different aspect ratios is something that’s in the works as well.  There are some upper limits on size with current technology – so if you’re looking for 300 DPI images at 36 inches x 36 inches you’re getting images at 10,800 pixels, and even small increases start to exponentially increase computing requirements. We’ve also considered alternate finishing options, like acrylics, but for now we’re keeping the offerings relatively simple.  

Company site:

AWS Glue Crawler – Multiple tables are found under location

I have been building and maintaining a data lake in AWS for the past year or so and it has been a learning experience to say the least. Recently I had an issue where a AWS Glue crawler stopped updating a table in the catalog that represented raw syslog data that was being imported in.

The error being shown was:

INFO : Multiple tables are found under location [S3 bucket and path]. Table [table name] is skipped.
Continue reading

Creating Data-Driven SSRS Reports in SQL Server Standard Edition

I recently had to resolve this issue. I was running SQL Server Standard Edition and needed to have an SSRS subscription that behaved like a data-driven subscription. Data driven subscriptions are available in Enterprise Edition SQL Server, but not Standard.

What is a Data-Driven Subscription

This is a very useful tool in the Enterprise Edition. A regular subscription is simply a scheduled time when a report will run and can be sent to email addresses or saved to a network share. The individual subscription will only run once and utilizes the same report parameters and recipient information.

A data-driven subscription lets you run a database query that returns no results or a set of results. The report is then run as many times as there are row results in the original database query. This allows you to 2 important things:

  • Not run the report if it does not have any meaningful results. e.g. Don’t send anything out.
  • Run multiple reports at once with customized parameters (who it is sent to, the subject of the email, the parameters used to generate the report, etc). This allows you to scale subscriptions really easily without having to go in and create a subscription for each recipient manually every time.

But I Do Not Have SQL Server Enterprise Edition

This means you do not have the data-driven feature when creating subscriptions. If you are doing a lot of data-driven report subscriptions, it may be worth your while to pay for that license as it will be less development time and more intuitive for users to understand what is happening than what I will describe below.

So we will have to come up with an alternative method to achieve something similar.

The Design

  • Publish an SSRS report if it is not published already.
  • Create a regular subscription using the SSRS interface.
    • Set any parameter values that are constant.
    • You may set the other parameters, but they will be overwritten anyways.
    • Set the schedule to have a stop date in the past, this makes sure it is active, but will not run on its own.
  • Create a stored procedure to run our report.
    • Code example in detail below.
    • Needs to run a query that provides how many times you want the report to run and what the override parameters should be.
    • Will loop over the results to:
      • Override the parameters stored in the table.
      • Execute the report.
      • Wait until the report is finished.
      • Continue.
  • Create a SQL Agent job to run the stored procedure on a schedule.

A Note Waiting For Each Report To Finish

Calling EXEC ReportServer.dbo.AddEvent does not block the script until the report is finished. It merely adds the report to the queue to be processed. If the report takes a while to run, this script may overwrite the parameters and settings being used. So it is important to have a loop monitoring the Events table to make sure the report has completed before continuing.

Stored Procedure Example

This example will determine how many reports need to be created and run each report consecutively by waiting for the report to finish before triggering another one.

--Steps to create data-driven like subscription in SQL Server 2016 Standard Edition:
--1. generate a subscription for a single user and note the subscription_id
--2. create stored procedure to update settings and generate reports
--3. schedule a job to run this procedure

-- Notes to Remember
-- Need to use a Job to run this and schedule.  
-- The subscription_id will be generated at the time the report subscription is created
-- The subscription should be set to active with a stop date in the past so it doesn't run on its own if not desired, but is an active report subscription.

IF EXISTS ( SELECT 1 FROM sysobjects WHERE id = object_id('DataDrivenSSRSSubscription_MyExampleReport) AND OBJECTPROPERTY(id, N'IsProcedure') = 1)
DROP PROCEDURE dbo.DataDrivenSSRSSubscription_MyExampleReport

CREATE PROCEDURE [dbo].[DataDrivenSSRSSubscription_MyExampleReport]
@subscription_id varchar(50),
@parameter_id int

    DECLARE @v_email varchar(256), @v_parameter1 varchar(256)
@settings varchar(4096), @params varchar(4096), @qry varchar(1024), @wait smallint
FROM Some_Table
WHERE Some_Table.parameter_id=@parameter_id

    OPEN db_cursor  
    FETCH NEXT FROM db_cursor INTO @v_email, @v_parameter1
    -- looping through the list
        -- wait until report has been cleared from the reporting queue
SELECT @wait = COUNT(*) FROM ReportServer.dbo.Event WHERE EventData=@subscription_id
WHILE @wait > 0
WAITFOR DELAY '00:00:01'
SELECT @wait = COUNT(*) FROM ReportServer.dbo.Event WHERE EventData=@subscription_id

        -- update parameters before generating report
SET @settings = '<ParameterValues>

SET @params = '<ParameterValues>
UPDATE ReportServer.dbo.Subscriptions
SET extensionsettings = @settings,
parameters = @params
WHERE subscriptionid = @subscription_id

        IF @@error = 0
            -- run report and send email
EXEC ReportServer.dbo.AddEvent @EventType='TimedSubscription',
        FETCH NEXT FROM db_cursor INTO  @v_email, @v_parameter1
    CLOSE db_cursor  
    DEALLOCATE db_cursor



These are some really good references that may be easier to understand. One note though, they do not cover “waiting for each report to finish before moving on to the next report.”

Unable to Download Blocked Gmail Attachment

I ran into an issue recently where I was trying to retrieve an attachment in an email and it was blocked. Gmail blocks the download of attachments it feels are a risk. Files with certain file extensions (like .exe), zip files that contain them, etc. The full listing and help from Google is here: .

The message you will see is:

Anti-virus warning 
– 1 attachment contains a virus or blocked file. Downloading this attachment is disabled.

I was searching for solutions and a lot of them involve asking the sender to send a different way or use a Google Drive folder or equivalent. In my case that would not work as the file was in an email I sent myself.

Eventually I found this article, which describes how to download the original email, open it in Windows Mail, and download the attachment from there. Very simple, free, and convenient to do. I imagine opening the email in a Mac email client would work as well.

XBox Kodi Unable to Open NFS Folder


I am running Kodi Alpha 3 on my XBox One and on my Surface.  Everything works fine on my Surface, but my XBox One in particular has this issue.

My media is stored a QNAP network attached storage on my local network. 

  • I try to add media by adding a file source. 
  • Add Videos -> Add Video Source -> Browse -> Network File System (NFS)
  • It automatically shows the IP of my NAS. 
  • I select the NAS IP name and it navigates to show me the root list of shared folders (Multimedia, Downloads, Public, etc).  
  • At this point I cannot descend any further into any of the folder names except for Public.  The other ones if I click on them just make an audible UI noise, but nothing happens.
  • I have checked the settings on the Multimedia folder, but they appear to be readonly for guest/everyone access.

On my Windows 10 Surface, the same procedure lets me descend into the Multimedia share and select a folder to index or view a file from.  It is like my XBoxOne is restricted or unable to go any further, but no error message is displayed.


I first posted about this on the Kodi forums in the article Xbox Kodi Unable to Open NFS Folder.

So my Kodi app on my Surface was working, because from my Surface in Windows Explorer I had logged into the NAS folders using a login/password.  The XBox One Kodi I had not done that (and not sure if you can).  I had to log into my QNAP and comb through the settings.  I had set up access as read only in one spot, but I needed to change a pick list to say “NFS host access” and then set “Access right” enabled.  Once I applied that setting, then I could descend into the folder from Kodi on the XBox One.   Was not able to upload my screenshot here, but here are step by step instructions for my NAS admin page.

1. Connect to your QNAP NAS admin page.
2. Open Control Panel
3. Select Privilege -> Shared Folders. 
4. You will now see a list of folders.
5. In the Actions column, hover over the icon that gives the tooltip that says “Edit Shared Folder Permission” and click it.
6. A window will appear that says “Edit Shared Folder Permission”. 
7. I did have “Guest Access Right” pick list set to “Read Only” here.
8. Change the “Select permission type” pick list to be “NFS host access”.
9. Enable the checkbox for “Access right”.
10. Click Apply.

You should be good to go now.  If you found you needed more steps, please post back here.  But this worked for me. 

I’m running the QNAP TS-231.  Firmware version: Build 20180810

Cloning Your Hard Drive to Another Hard Drive

A friend of mine the other day had their hard drive approaching death. It was grinding away and had a number of errors occurring. It was time to replace it.

After picking up a hard drive that was almost double the size, he gave it to me as I offered to install it.

There are two main things you need to do when upgrading or replacing your hard drive:

  • Installing the drive.
  • Copy over your data.

Installing the drive is the easy part. Just open up the case, find a spot that is available and the data and power cables can reach the drive from there. Plug everything in, turn on the computer and make sure it can detect the drive.

Continue reading

Recovering Pictures or Files on Flash Memory

I had a scary moment on my most recent trip. My card appeared to fail after I had taken a week’s worth of pictures in Nepal.

My Nikon D70s started flashing “For”, which indicates the compact flash card inside needs to be formatted. I was unable to view the pictures and if I put it into a card reader and tried to access it on Windows, it just wanted to format the card.

I waited a month, until I arrived home, to try and recover the pictures. I tried 8 different programs and I found two that were able to do it.

RescuePro was one of them. They let you download a trial of it and see if it will actually work before you have to buy. It will access the flash card and then scan it. After awhile, it shows you thumbnails and will let you recover a small number of the files for free. If you see your files and think it is worth it, then you can pay the US$40 for a license.

Active File Recovery is the other one that worked. This program is a little more full-featured. It can recover files on hard drives as well. RescuePro was strictly for flash cards.

Anyhow, if you have ever deleted, formatted, corrupted, or had some other failure with files or flash cards. Don’t just erase the card and start from scratch thinking you lost everything. Download a trial copy of RescuePro from the link above and see if you can spot your missing items. It will be well worth the $40 in a lot of cases.

Win32 Application and Logging To The Console

I have been writing demo applications using OpenGL recently in C++. I documented how to set up the environment and create a project in my article OpenGL and Visual Studio Express 2008. I started out by writing the application as a Win32 application. This was a problem though.When you are doing it in a Win32 project instead of a Win32 Console project it makes it very hard to do simple debugging using print statements. If you are like me, I like to scatter prinf or cout statements through different parts of my code so I can trace the progress and examine variables during development. It makes it very easy.If you use these statements in a Win32 project however, this output does not get printed out to the console or anywhere for that matter. It is just eaten and no errors are incurred.

Continue reading

AC3 Encoded Sound Is Too Quiet

I have recently been watching hi definition video downloads on my laptop. Their sound was encoded using AC3 and I found that I was not able to get the sound loud enough on my laptop to watch the movie enjoyably.

The movies were mkv format (otherwise known as Matroska).

Fortunately, I found a very useful AC3 configuration too called the AC3 Filter that allows you to boost the sounds volume and push your speakers a little farther. You can download the program off their site and install it.

Just open it up, adjust the gain or any other settings, restart your media player, and enjoy. The only catch is that you will need to restart your media playing application anytime you change a setting to see its effect.

Awk – Error – Unterminated String

I was frustrated using awk recently. I had created a awk file to do some batch processing of text file information. Anyhow, I had a large text section to create an SQL statement from. It spanned multiple lines and I had used a backslash “\” to indicate the string continued on the next line.

I had a syntax problem however. It was saying I had an unterminated string. I googled for the answer and checked to make sure every line of my text section had a backslash (which it did) and I couldn’t figure it out.

Below is the error I had.

awk: query.awk:2: print "SELECT \awk: query.awk:2:       ^ unterminated string

Anyhow, last straw was to go to everyline that had the backslash at the end and remove any spaces at that came after the backslash (so between the slash and the true end of the line). This fixed my problem.

« Older posts